本文主要討論的是GP中在創建表時可以選擇的表的存儲方式,有兩類:
1、行存儲,列存儲
2、堆存儲還是追加優化存儲
首先我們來討論一下行存和列存
行存儲的具體形式:
行方向是傳統的存儲數據庫元組的方式。
組成一行的列被連續地存儲在磁盤上,因此整個行可以被以單次I/O從磁盤上讀出。
行存儲是行爲單位存儲數據,一行中越是靠後的列,那麼查詢需要的cost相對越大,這個以前oracle做過相應比較,都是一樣的道理,行存儲更適合OLTP的系統
列存儲的具體形式
面向列的方式把列值在磁盤上存在一起。對每一列都會創建一個單獨的文件。
如果表被分區,則會對每個列和分區的組合創建一個單獨的文件。當一個查詢在一個有很多列的列存表中訪問少量列時,I/O代價會比行存表要減少很多,因爲不必從磁盤上檢索沒有被引用的列。
行存的適用場景:
更新並且頻繁執行插入的事務的交易型負載
查詢中需要單個行的很多列
列存的適用場景:
查詢中只訪問列的一個小集合
定期更新單個列但不修改行中其他列的表
爲追求壓縮
列存可以看做是對行存的一種優化:
面向列的存儲是爲了讀操作而優化,但它並未對寫操作優化,一行的列值必須被寫入到磁盤上的不同位置。
列存的另一個好處是,同一種數據類型的值集合可以用比混合類型值集合更少的空間存儲在一起,因此列存表比行存表使用的磁盤空間更少(進而導致需要更少的磁盤I/O)。列存表的壓縮效果也比行存表更好。
有必要理解每個列都是Greenplum數據庫中每個Segment上一個單獨的物理文件。
然後我們談談堆存儲和最佳優化存儲:
堆表,我們普通的創建的表默認都是堆表,適合頻繁的更新刪除操作的小表,適合OLTP系統。
抽象點就是說,下面兩種情況推薦適用默認的堆表:
將收到反覆UPDATE、DELETE以及單個INSERT操作的表和分區。
將收到併發UPDATE、DELETE以及INSERT操作的表和分區。
AO表可以看做是對默認堆表的優化:
AO表,適合批量數據寫入,不適合單行的insert,適合大表使用,所以一般用在數據倉庫系統,適合OLAP系統。
抽象的來說,下面三種情況推薦使用AO表:
爲初始裝載後就很少被更新並且後續只會以批操作執行插入的表和分區使用追加優化存儲。
絕不要在追加優化表上執行單個INSERT、UPDATE或者DELETE操作。
併發的批量INSERT操作可以被執行但是絕不執行併發的批量UPDATE或者DELETE操作。
追加優化表中被更新和刪除的行所佔用的空間不會像堆表那樣被有效地回收及重用,因此追加優化存儲模型不適合於頻繁更新的表。它的設計目標是用於一次裝載、很少更新且頻繁進行分析查詢處理的大型表。