greenplum 数据库如何增加列_Greenplum行存与列存的选择以及转换方法-阿里云开发者社区...
背景
數據在數據庫中的存儲形式多種多樣,比較常見的如
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的需求更旺盛。
這種情況下,我們的需求是將老的分區轉換為列存儲,怎么做呢?
例子
創建分區表,選擇行存儲
create table t_digoal (id int, info text, crt_time timestamp) distributed by (id) partition by range(crt_time) (start (date '2016-08-01') inclusive end (date '2016-12-01') exclusive every (interval '1 day'));
查看分區定義
postgres=> select * from pg_partitions;
-[ RECORD 1 ]------------+----------------------------------------------------------------------------------------------------------------------------------------------
schemaname | public
tablename | t_digoal
partitionschemaname | public
partitiontablename | t_digoal_1_prt_1
partitionname |
parentpartitiontablename |
parentpartitionname |
partitiontype | range
partitionlevel | 0
partitionrank | 1
partitionposition | 1
partitionlistvalues |
partitionrangestart | '2016-08-01 00:00:00'::timestamp without time zone
partitionstartinclusive | t
partitionrangeend | '2016-08-02 00:00:00'::timestamp without time zone
partitionendinclusive | f
partitioneveryclause | '1 day'::interval
partitionisdefault | f
partitionboundary | START ('2016-08-01 00:00:00'::timestamp without time zone) END ('2016-08-02 00:00:00'::timestamp without time zone) EVERY ('1 day'::interval)
parenttablespace | pg_default
partitiontablespace | pg_default
-[ RECORD 2 ]------------+----------------------------------------------------------------------------------------------------------------------------------------------
schemaname | public
tablename | t_digoal
partitionschemaname | public
partitiontablename | t_digoal_1_prt_2
partitionname |
parentpartitiontablename |
parentpartitionname |
partitiontype | range
partitionlevel | 0
partitionrank | 2
partitionposition | 2
partitionlistvalues |
partitionrangestart | '2016-08-02 00:00:00'::timestamp without time zone
partitionstartinclusive | t
partitionrangeend | '2016-08-03 00:00:00'::timestamp without time zone
partitionendinclusive | f
partitioneveryclause | '1 day'::interval
partitionisdefault | f
partitionboundary | START ('2016-08-02 00:00:00'::timestamp without time zone) END ('2016-08-03 00:00:00'::timestamp without time zone) EVERY ('1 day'::interval)
parenttablespace | pg_default
partitiontablespace | pg_default
創建列存單表,用于交換分區
postgres=> create table t_digoal_col(id int, info text, crt_time timestamp) with (appendonly=true, ORIENTATION=column) distributed by (id);
CREATE TABLE
將歷史分區數據插入列存儲的交換分區
insert into t_digoal_col select * from t_digoal_1_prt_1;
指定對應的rank,交換分區
alter table t_digoal exchange partition for (rank(1)) with table t_digoal_col with validation;
可以使用 without validation 加快速度。
祝大家玩得開心,歡迎隨時來 阿里云促膝長談業務需求 ,恭候光臨。
阿里云的小伙伴們加油,努力 做好內核與服務,打造最貼地氣的云數據庫 。
總結
以上是生活随笔為你收集整理的greenplum 数据库如何增加列_Greenplum行存与列存的选择以及转换方法-阿里云开发者社区...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个女生简短个性签名
- 下一篇: app图标圆角角度_?APP图标造型分析