前言
本特性自MogDB 3.1.0版本开始引入。5.0版本的并行索引扫描支持了分区表,提升了部分场景的性能。
openGauss只支持并行的segscan,通过在优化器中根据并行度直接计算每个线程要访问的页面号码,然后每个线程直接扫描对应的页面。在包含约束条件的扫描中,只能用并行segscan然后进行条件过滤或者是单线程的索引扫描,性能很低。
MogDB通过将查询任务分解为多个并行的子任务,同时扫描多个索引,可以避免扫描全部数据文件,提高查询效率,加快数据访问速度。使用并行索引扫描特性可以预计获得大约25%左右的性能提升,而对于整体执行来说,预计可以获得大约10%左右的性能提升。
索引并行扫描原理:
- 1.多个线程同步对btree进行扫描,根据约束条件找到起始付置,各线程交替进行indexpage的获取和读取;
- 2.各线程根据获得的indextuple来进行数据tuple的获取,各线程不需要同步,并行执行,加快数据访问速度。
测试验证
GLOBAL索引
-- 1. 创建分区表,并插入数据。 CREATE TABLE parallel_partition_index_01 ( c1 int, c2 int, c3 int ) PARTITION BY RANGE(c1) ( PARTITION P1 VALUES LESS THAN(2000), PARTITION P2 VALUES LESS THAN(4000), PARTITION P3 VALUES LESS THAN(6000), PARTITION P4 VALUES LESS THAN(MAXVALUE) )enable row movement; INSERT INTO parallel_partition_index_01 VALUES (generate_series(1, 10000), generate_series(1,10000), generate_series(1, 10000)); -- 2. 创建索引。 CREATE INDEX index_parallel_partition_index_01 on parallel_partition_index_01(c1) GLOBAL; -- 3. 关闭其他扫描类型,如seqscan、bitmapscan、indexonlyscan等。 SET enable_seqscan = OFF; SET enable_bitmapscan = OFF; SET enable_indexonlyscan = OFF; -- 4. 打开并行开关,设置线程之间通信同步代价(smp_thread_cost)。 -- 说明: smp_thread_cost参数值调低可以促使优化器优先选择并行。 SET query_dop = 2; SET smp_thread_cost = 0; -- 5. 执行查询操作。 SELECT * FROM parallel_partition_index_01 WHERE c1=100; c1 | c2 | c3 -----+-----+----- 100 | 100 | 100 (1 row) -- 6. 执行EXPLAIN语句查看执行计划信息。 EXPLAIN (COSTS OFF) SELECT * FROM parallel_partition_index_01 WHERE c1<1000; QUERY PLAN ----------------------------------------------------------------------------------------- Streaming(type: LOCAL GATHER dop: 1/2) -> Index Scan using index_parallel_partition_index_01 on parallel_partition_index_01 Index Cond: (c1 < 1000) (3 rows)
LOCAL索引
-- 1. 创建分区表,并插入数据。 CREATE TABLE parallel_partition_index_01 ( c1 int, c2 int, c3 int ) PARTITION BY RANGE(c1) ( PARTITION P1 VALUES LESS THAN(2000), PARTITION P2 VALUES LESS THAN(4000), PARTITION P3 VALUES LESS THAN(6000), PARTITION P4 VALUES LESS THAN(MAXVALUE) )enable row movement; INSERT INTO parallel_partition_index_01 VALUES (generate_series(1, 10000), generate_series(1,10000), generate_series(1, 10000)); -- 2. 创建索引。 CREATE INDEX index_parallel_partition_index_01 on parallel_partition_index_01(c1) LOCAL; -- 3. 关闭其他扫描类型,如seqscan、bitmapscan、indexonlyscan等。 SET enable_seqscan = OFF; SET enable_bitmapscan = OFF; SET enable_indexonlyscan = OFF; -- 4. 打开并行开关,设置线程之间通信同步代价(smp_thread_cost)。 --说明:smp_thread_cost参数值调低可以促使优化器优先选择并行。 SET query_dop = 2; SET smp_thread_cost = 0; -- 5. 执行查询操作。 SELECT * FROM parallel_partition_index_01 WHERE c1=100; c1 | c2 | c3 -----+-----+----- 100 | 100 | 100 (1 row) -- 6. 执行EXPLAIN语句查看执行计划信息。 EXPLAIN (COSTS OFF) SELECT * FROM parallel_partition_index_01 WHERE c1<1000; QUERY PLAN ----------------------------------------------------------------------------------------- Streaming(type: LOCAL GATHER dop: 1/2) -> Partition Iterator Iterations: 1 Selected Partitions: 1 -> Partitioned Index Scan using index_parallel_partition_index_01 on parallel_partition_index_01 Index Cond: (c1 < 1000) (6 rows) -- 7.开启enable_bitmapscan MogDB=# set enable_bitmapscan=on; SET --8.说明支持bitmapscan索引并行扫描。 MogDB=# EXPLAIN (COSTS OFF) SELECT * FROM parallel_partition_index_01 WHERE c1<1000; QUERY PLAN -------------------------------------------------------------------------------------- Streaming(type: LOCAL GATHER dop: 1/2) -> Partition Iterator Iterations: 1 Selected Partitions: 1 -> Partitioned Bitmap Heap Scan on parallel_partition_index_01 Recheck Cond: (c1 < 1000) -> Partitioned Bitmap Index Scan on index_parallel_partition_index_01 Index Cond: (c1 < 1000) --9.开启indexonlyscan扫描类型 SET enable_seqscan = OFF; SET enable_bitmapscan = OFF; set enable_indexscan=off; SET enable_indexonlyscan = on; --10.说明支持indexonlyscan索引并行扫描。 MogDB=# EXPLAIN (COSTS OFF) SELECT c1 FROM parallel_partition_index_01 ; QUERY PLAN ---------------------------------------------------------------------------------------------------------------- Streaming(type: LOCAL GATHER dop: 1/2) -> Partition Iterator Iterations: 4 Selected Partitions: 1..4 -> Partitioned Index Only Scan using index_parallel_partition_index_01 on parallel_partition_index_01 (5 rows)
知识总结
主要包含三种方式:indexscan、indexonlyscan以及bitmapscan。
- indexscan:在对数据表进行范围查询时,可以通过索引定位到起始和结束位置,先扫描索引数据,再根据扫描结果对数据文件进行并行扫描,提升查询效率。
- indexonlyscan:在进行表扫描时,当目标列都包含在索引中时,可以仅扫描索引数据,减少需要扫描的文件,同时可根据约束条件来对确定范围的索引数据进行并行扫描。
- bitmapscan:在进行表扫描时,将索引扫描分为两个阶段。先并行扫描索引文件,获取要扫描的所有数据文件页;然后再并行扫描数据文件页,这样可以减少数据文件的随机访问和读取次数。
技术限制
- 使用该功能需要打开并行开关,即设置query_dop的值大于1。
- 并行索引扫描仅支持BTree索引。
支持astore存储类型,不支持ustore、cstore存储类型。
参考文档
https://docs.mogdb.io/zh/mogdb/v5.0/parallel-index-scan#%E7%89%B9%E6%80%A7%E6%8F%8F%E8%BF%B0
https://docs.mogdb.io/zh/mogdb/v5.0/optimizer-cost-constants
本文由mdnice多平台发布
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。