openGauss新特性 | HTAP新特性介绍
一、行列融合功能简介
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数据分析的整体查询效率。