一、為什么列存儲(chǔ)數(shù)據(jù)庫(kù)讀取速度會(huì)比傳統(tǒng)的行數(shù)據(jù)庫(kù)快
列存儲(chǔ)的數(shù)據(jù)庫(kù)更適合OLAP,行存儲(chǔ)的數(shù)據(jù)庫(kù)更適合OLTP所謂的快只是針對(duì)于進(jìn)行olap操作而言。我們知道,數(shù)據(jù)在存儲(chǔ)中的基本單位為頁(yè),這也是進(jìn)行數(shù)據(jù)讀取時(shí)候基本單位,一次讀取就是一次IO操作。
以行方式查詢(xún)(在有適當(dāng)?shù)乃饕闆r下),那么,執(zhí)行一次以上查詢(xún),只需要掃描一次page1就可以了。
以列方式查詢(xún),需要投其掃描page1 和page2共2次,分別取得字段1,字段2的單行值。
OK,我們換成olap的典型查詢(xún)
select avg(字段2) from table
–(注意,這里假設(shè)字段2為一個(gè)整型數(shù)據(jù),而且無(wú)where條件限制,即需要掃描全部數(shù)據(jù))
對(duì)于行存儲(chǔ),這個(gè)查詢(xún)需要兩次IO將全部數(shù)據(jù)放入內(nèi)存后,進(jìn)行頁(yè)間數(shù)據(jù)的跳讀(類(lèi)隨機(jī)讀取),對(duì)于列存儲(chǔ),只需要一次IO將page2放入內(nèi)存后進(jìn)行連續(xù)讀取,如果字段2還有多頁(yè)的話(huà),也都是進(jìn)行的物理連續(xù)讀取
也就是說(shuō),在進(jìn)行olap操作時(shí)候,不僅是減小了IO次數(shù),而且把隨機(jī)讀取變?yōu)榱诉B續(xù)讀取。
列式存儲(chǔ)把相同類(lèi)型的數(shù)據(jù)歸在一起,壓縮比可以很高,通常能到10%~25%。數(shù)據(jù)庫(kù)的瓶頸通常在IO,很高的壓縮比,可以大大減輕數(shù)據(jù)讀取的壓力,提高響應(yīng)速度。
除去字符串類(lèi)型,其他類(lèi)型的字段通常是固定長(zhǎng)度的,而且在磁盤(pán)和內(nèi)存的字節(jié)順序通常是一致的,可以直接映射,省去了解析的過(guò)程。而在行存儲(chǔ)中,只要有變長(zhǎng)的字段存在,需要逐行逐字段的解析。
延伸閱讀:
二、列存儲(chǔ)的特點(diǎn)
在讀取數(shù)據(jù)時(shí),SQL?Server每次都把所需數(shù)據(jù)所在的整個(gè)Page讀取到內(nèi)存中,Page是數(shù)據(jù)讀取的最小單位。如果采用行存儲(chǔ),每一個(gè)Page都存儲(chǔ)所有列的數(shù)據(jù),每行的Size決定了單個(gè)Page能夠存儲(chǔ)的數(shù)據(jù)行數(shù)量。
我們可以粗略計(jì)算一下,如果一個(gè)數(shù)據(jù)行有10列,每列的平均Size是10B,一行的Size是100B,那么單個(gè)Page非常多存儲(chǔ)80行(8060B/100B);如果采用列存儲(chǔ)模式,那么單個(gè)Page可以存儲(chǔ)806行(8060B/10B)。就單個(gè)Page存儲(chǔ)的數(shù)據(jù)行數(shù)量而言,列存儲(chǔ)是行存儲(chǔ)的10倍,SQL Server引擎把一個(gè)Page讀取到內(nèi)存中,能夠獲取的數(shù)據(jù)行數(shù)量成10倍增加。
因此,采用列存儲(chǔ)模式時(shí),每一個(gè)Page能夠存儲(chǔ)更多的數(shù)據(jù)行。在加載列存儲(chǔ)數(shù)據(jù)時(shí),SQL Server只需要消耗少量的IO,就能把某一列的全部數(shù)據(jù)加載到緩存中。當(dāng)從列很多的大表中讀取幾個(gè)列時(shí),相比傳統(tǒng)的行存儲(chǔ)(Row Store)模式,列存儲(chǔ)(Column Store)能夠成千上萬(wàn)倍地提高數(shù)據(jù)的讀取速度和查詢(xún)性能。