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