一、行列融合功能簡介
HTAP 行列融合特性在單機、主備場景下,通過節點的行列雙格式內存模式,實現openGauss HTAP一體化數據庫架構。 通過高效的行列轉換技術方案,節點讀取磁盤行存數據,生成列存儲單元(Column Unit)存儲至節點的列緩存中;支持節點通過代價估算生成列緩存查詢計劃,通過列存查詢大幅提升復雜OLAP場景下的數據分析效率,使數據庫同時具備較強的TP和AP能力。在主備場景下,列緩存數據均存儲在備節點,通過日志讀取回放,同步主節點在OLTP場景下大量的行數據變更,以維持列緩存數據的新鮮度。
openGauss主備集群場景下,支持備節點形成行列雙格式內存形式。針對主節點的行級修改,備節點通過日志同步主節點修改,將對應修改寫入增量表中。同時,備節點后臺啟動的同步線程,將增量表中存儲的行存修改同步至列存緩存中。用戶在備節點發起的OLAP大型數據分析請求,將先通過邏輯判斷是否已有查詢表的列緩存數據,并根據代價計算形成基于列緩存的查詢計劃。
二、行列融合參數介紹
enable_imcsscan
參數說明:開啟列緩存查詢功能。
開啟后,openGauss支持通過列緩存掃描,執行計劃將根據表是否已行列轉換及代價估算明確最終是否通過列緩存掃描。
取值范圍:布爾型
默認值:off
enable_parallel_populate
參數說明:開啟并行行列轉換。
取值范圍:布爾型
默認值:on
max_imcs_cache
參數說明:設置列緩存所使用的緩沖區的大小。
取值范圍:整型,102400~INT_MAX,單位為kB。
默認值:100MB
設置建議:行列融合使用max_imcs_cache設置的緩沖區進行列緩存的存儲,當增大max_imcs_cache配置時,需增大max_process_memory的大小以符合內存的基本邏輯校驗。當行列轉換的表數據大于配置的列緩存存儲空間時,系統將存儲臨時文件。
三、行列融合操作介紹
HTAP 行列融合特性支持用戶針對全表、表指定列、指定分區進行行列轉換及清除已有列緩存操作。
對指定行表進行行列轉換
轉換方式1:全表轉換
?????
sql
ALTER?TABLE?table_name IMCSTORED;
轉換方式2:表部分列轉換
sql
ALTER?TABLE?table_name IMCSTORED(column_name_list);
轉換方式3:對分區表的指定分區轉換
sql
ALTER?TABLE?table_name MODIFY?PARTITION?partition_name IMCSTORED;
??????
轉換方式4:對分區表的指定分區的部分列轉換,支持不同分區轉換不同列???????
sql
ALTER?TABLE?table_name MODIFY?PARTITION?partition_name IMCSTORED(column_name_list);
清除已轉換的列緩存
清除方式1:對指定行表做全量列緩存清除???????
sql
ALTER?TABLE?table_name UNIMCSTORED;
清除方式2:對分區表的指定分區做列緩存清除???????
sql
ALTER?TABLE?table_name MODIFY?PARTITION?partition_name UNIMCSTORED;
普通表示例???????
sql
--創建普通表
openGauss=#?CREATE?TABLE?test
(id ??INT,name VARCHAR2(40),dept_id ? ?INT
);
CREATE?TABLE
--對該表進行行列轉換
openGauss=#?ALTER?TABLE?test IMCSTORED;
ALTER?TABLE
--查詢該表,執行行存計劃
openGauss=# EXPLAIN?SELECT?*?FROM?test;QUERY PLAN ? ? ? ? ? ? ? ? ? ? ? ?
---------------------------------------------------------Seq Scan?on?test ?(cost=0.00..16.01?rows=601?width=106)
(1?row)
--開啟列存掃描計劃
openGauss=#?SET?enable_imcsscan=on;
SET
--查詢該表,執行列存計劃
openGauss=# EXPLAIN?SELECT?*?FROM?test;QUERY PLAN ? ? ? ? ? ? ? ? ? ? ? ? ? ??
--------------------------------------------------------------------Row?Adapter ?(cost=10.60..10.60?rows=601?width=106)->? IMCStore Scan?on?test ?(cost=0.00..10.60?rows=601?width=106)
(2?rows)
--對該表清除列緩存
openGauss=#?ALTER?TABLE?test UNIMCSTORED;
ALTER?TABLE
--對該表部分列進行行列轉換
openGauss=#?ALTER?TABLE?test IMCSTORED(id);
ALTER?TABLE
分區表示例
sql
--創建分區表
openGauss=#?CREATE?TABLE?test_partition
(id ??INT,name VARCHAR2(40),dept_id ? ?INT,age ?INT
)?PARTITION?BY?RANGE(dept_id) SUBPARTITION?BY?RANGE?(age)?
(PARTITION?dept_id_p1?VALUES?LESS THAN (5) (SUBPARTITION age_sub_p1?VALUES?LESS THAN (25),SUBPARTITION age_sub_p2?VALUES?LESS THAN (35),SUBPARTITION age_sub_p3?VALUES?LESS THAN (maxvalue)),PARTITION?dept_id_p2?VALUES?LESS THAN (maxvalue) (SUBPARTITION age_sub_p4?VALUES?LESS THAN (25),SUBPARTITION age_sub_p5?VALUES?LESS THAN (35),SUBPARTITION age_sub_p6?VALUES?LESS THAN (maxvalue))
);
CREATE?TABLE
--對該表進行全量行列轉換,即所有分區、所有列
openGauss=#?ALTER?TABLE?test_partition IMCSTORED;
ALTER?TABLE
--對該表清除列緩存
openGauss=#?ALTER?TABLE?test_partition UNIMCSTORED;
ALTER?TABLE
--對該表 dept_id_p1 分區的所有列進行行列轉換
openGauss=#?ALTER?TABLE?test_partition MODIFY?PARTITION?dept_id_p1 IMCSTORED;
ALTER?TABLE
--對該表 dept_id_p1 分區清除列緩存
openGauss=#?ALTER?TABLE?test_partition MODIFY?PARTITION?dept_id_p1 UNIMCSTORED;
ALTER?TABLE
--對該表 dept_id_p1 分區的 id, name 列進行行列轉換
openGauss=#?ALTER?TABLE?test_partition MODIFY?PARTITION?dept_id_p1 IMCSTORED(id, name);
ALTER?TABLE
--對該表 dept_id_p2 分區的 name, age 列進行行列轉換
openGauss=#?ALTER?TABLE?test_partition MODIFY?PARTITION?dept_id_p2 IMCSTORED(name, age);
ALTER?TABLE
--開啟列存掃描計劃
openGauss=#?SET?enable_imcsscan=on;
SET
--查詢該表 dept_id_p1 分區的 id, name 列, 執行列存計劃
openGauss=# EXPLAIN?SELECT?id, name?FROM?test_partition?PARTITION(dept_id_p1);QUERY PLAN ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
-----------------------------------------------------------------------------------------------Row?Adapter ?(cost=5.58..5.58?rows=583?width=102)->? Vector?Partition?Iterator ?(cost=0.00..5.58?rows=583?width=102)Iterations:?1, Sub Iterations:?3->? Partitioned IMCStore Scan?on?test_partition ?(cost=0.00..5.58?rows=583?width=102)Selected Partitions: ?1Selected Subpartitions: ?ALL
(6?rows)
--查詢該表 dept_id_p2 分區的 name, age 列, 執行列存計劃
openGauss=# EXPLAIN?SELECT?name, age?FROM?test_partition?PARTITION(dept_id_p2);QUERY PLAN ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
-----------------------------------------------------------------------------------------------Row?Adapter ?(cost=5.58..5.58?rows=583?width=102)->? Vector?Partition?Iterator ?(cost=0.00..5.58?rows=583?width=102)Iterations:?1, Sub Iterations:?3->? Partitioned IMCStore Scan?on?test_partition ?(cost=0.00..5.58?rows=583?width=102)Selected Partitions: ?2Selected Subpartitions: ?ALL
(6?rows)
--查詢整張表 id, name 列, dept_id_p2 未轉換 id 列, 執行行存計劃
openGauss=# EXPLAIN?SELECT?name, age?FROM?test_partition;QUERY PLAN ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
-------------------------------------------------------------------------------------Partition?Iterator ?(cost=0.00..15.83?rows=583?width=102)Iterations:?2, Sub Iterations:?6->? Partitioned Seq Scan?on?test_partition ?(cost=0.00..15.83?rows=583?width=102)Selected Partitions: ?1..2Selected Subpartitions: ?ALL
(5?rows)
--查詢整張表 name 列, dept_id_p1、dept_id_p2 均轉換 name 列, 因此執行列存計劃
openGauss=# EXPLAIN?SELECT?name?FROM?test_partition;QUERY PLAN ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
-----------------------------------------------------------------------------------------------Row?Adapter ?(cost=10.58..10.58?rows=583?width=98)->? Vector?Partition?Iterator ?(cost=0.00..10.58?rows=583?width=98)Iterations:?2, Sub Iterations:?6->? Partitioned IMCStore Scan?on?test_partition ?(cost=0.00..10.58?rows=583?width=98)Selected Partitions: ?1..2Selected Subpartitions: ?ALL
(6?rows)
總結???????
openGauss 通過簡單的指令設置,有效利用備節點可用內存空間進行行存數據的列緩存轉換及存儲(In-Memory-Column-Store)。考慮列存的查詢優勢,在數據量龐大,表結構復雜,而用戶僅關注部分列數據的查詢的場景下,行列轉換后的列緩存可有效提升企業執行大型復雜OLAP數據分析的整體查詢效率。