資料在資料庫中的存儲形式多種多樣,比較常見的如
1. postgresql的堆表,以行的形式存儲,(當變成字段壓縮後的長度超過資料塊的四分之一時,會以toast的形式存儲到toast表)。
2. mysql innodb則是以b+tree形式存儲的。
在資料倉庫産品中,如greenplum,支援行存,也支援列存。
還有很多存儲格式,本文将讨論行存和列存應該如何選擇呢?
greenplum行存儲(堆表)的優勢在哪裡?
資料順序寫入block中,持續寫入的情況下,一條記錄命中在一個塊中,io開銷相對比較小,速度較快。
查詢多個字段時,因為記錄在一個塊中命中,速度較快。
greenplum行存儲(堆表)的劣勢在哪裡?
查詢少量字段時,也要通路整條記錄,造成一定的io浪費。
行存儲的壓縮比有限。
行存儲适合非常典型的oltp應用場景。
greenplum列存儲的優勢在哪裡?
資料按列存儲,壓縮比可以做到很高。
當查詢少量字段時,掃描的塊更少,可以節約io還能提升效率。
greenplum列存儲的劣勢在哪裡?
因為是按列存儲的,當需要查詢大量字段時,或者查詢的記錄數偏少時,會造成離散io較多。
例如查詢1條記錄的20個列,行存儲可能隻需要掃描1個塊,而列存儲至少需要掃描20個塊。
由于io的放大,列存儲不适合oltp的場景,如有大量的更新,查詢操作。
列存儲适合非常典型的olap應用場景,按列做較大範圍的聚合分析,或者join分析。
建表時,在with(storage parameter)中指定
或者在分區的with(storage parameter)中指定
或者在子分區的with(storage parameter)中指定
是以greenplum的存儲格式支援到了子分區這個級别,一張表(指父表)可以混合使用行存儲與列存儲。
例如使用者如果有一張按時間分區的表,最近1個月的查詢類似oltp的請求,需要查詢較多字段,而一個月以前的表則olap的需求更旺盛。
這種情況下,我們的需求是将老的分區轉換為列存儲,怎麼做呢?
例子
建立分區表,選擇行存儲
檢視分區定義
建立列存單表,用于交換分區
将曆史分區資料插入列存儲的交換分區
指定對應的rank,交換分區
可以使用 without validation 加快速度。
祝大家玩得開心,歡迎随時來 阿裡雲促膝長談業務需求 ,恭候光臨。
阿裡雲的小夥伴們加油,努力 做好核心與服務,打造最貼地氣的雲資料庫 。