gp堆表AO表、行存和列存


堆表AO表

1、堆表,實際上就是PG的堆存儲,堆表的所有變更都會產生REDO,可以實現時間點恢復。但是堆表不能實現邏輯增量備份(因為表的任意一個數據塊都有可能變更,不方便通過堆存儲來記錄位點。)。

一個事務結束時,通過clog以及REDO來實現它的可靠性。同時支持通過REDO來構建MIRROR節點實現數據冗余。

2、AO表,看名字就知道,只追加的存儲,刪除更新數據時,通過另一個BITMAP文件來標記被刪除的行,通過bit以及偏移對齊來判定AO表上的某一行是否被刪除。

事務結束時,需要調用FSYNC,記錄最后一次寫入對應的數據塊的偏移。(並且這個數據塊即使只有一條記錄,下次再發起事務又會重新追加一個數據塊)同時發送對應的數據塊給MIRROR實現數據冗余。

因此AO表不適合小事務,因為每次事務結束都會FSYNC,同時事務結束后這個數據塊即使有空余也不會被復用。(你可以測試一下,AO表單條提交的IO放大很嚴重)。

雖然如此,AO表非常適合OLAP場景,批量的數據寫入,高壓縮比,邏輯備份支持增量備份,因此每次記錄備份到的偏移量即可。加上每次備份全量的BITMAP刪除標記(很小)。

 

行存和列存的原理

1、行存,以行為形式組織存儲,一行是一個tuple,存在一起。當需要讀取某列時,需要將這列前面的所有列都進行deform,所以訪問第一列和訪問最后一列的成本實際上是不一樣的。

在這篇文檔中,有deform的詳細介紹。《PostgreSQL 向量化執行插件(瓦片式實現) 10x提速OLAP》

行存小結:

全表掃描要掃描更多的數據塊。

壓縮比較低。

讀取任意列的成本不一樣,越靠后的列,成本越高。

不適合向量計算、JIT架構。(簡單來說,就是不適合批處理形式的計算)

需要REWRITE表時,需要對全表進行REWRITE,例如加字段有默認值。

2、列存,以列為形式組織存儲,每列對應一個或一批文件。讀取任一列的成本是一樣的,但是如果要讀取多列,需要訪問多個文件,訪問的列越多,開銷越大。

列存小結:

壓縮比高。

僅僅支持AO存儲(后面會將)。

讀取任意列的成本是一樣的。

非常適合向量計算、JIT架構。對大批量數據的訪問和統計,效率更高。

讀取很多列時,由於需要訪問更多的文件,成本更高。例如查詢明細。

需要REWRITE表時,不需要對全表操作,例如加字段有默認值,只是添加字段對應的那個文件。

什么時候選擇行存

如果OLTP的需求偏多,例如經常需要查詢表的明細(輸出很多列),需要更多的更新和刪除操作時。可以考慮行存。

什么時候選擇列存

如果OLAP的需求偏多,經常需要對數據進行統計時,選擇列存。

需要比較高的壓縮比時,選擇列存。

如果用戶有混合需求,可以采用分區表,例如按時間維度的需求分區,近期的數據明細查詢多,那就使用行存,對歷史的數據統計需求多那就使用列存。

sql

CREATE TABLE table_xx(id int,n1 varchar,n2 varchar,n3 varchar)

WITH
(appendonly=
true
,orientation=
column
,compresstype=
zlib
,COMPRESSLEVEL=
5
)

distributed by (id);

①QuickLZ - 低壓縮率、低cpu消耗、壓縮數據塊

②zlib - 高壓縮率、低速

(注: QuickLZ的壓縮級別只有level1,zlib能夠設置從1-9)

建表的時候加上 with(appendonly=true) 就可以指定表是Appendonly表。如果需要建壓縮表,則加上 with(appendonly=true,compresslevel=5),其中compresslevel是壓縮率,取值為1~9,一般選擇5就足夠

appendonly=true, orientation=column這兩個屬性決定了這是列存壓縮表。

compresstype: 壓縮方式,支持zlip,rte等

compresslevel: 壓縮級別,0-9,一般壓縮級別為5即可

blocksize: 塊大小8KB-2MB, 大小在8192 - 2097152 之間並且是8192的倍數

distributed by(fieldname1,fieldname2) : 分布鍵可以以多個設置,也可以設置一個,GP會hash分布到不同的segment上

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM