likes
comments
collection
share

Mogdb性能增强之并行索引扫描

作者站长头像
站长
· 阅读数 3

前言

本特性自MogDB 3.1.0版本开始引入。5.0版本的并行索引扫描支持了分区表,提升了部分场景的性能。

openGauss只支持并行的segscan,通过在优化器中根据并行度直接计算每个线程要访问的页面号码,然后每个线程直接扫描对应的页面。在包含约束条件的扫描中,只能用并行segscan然后进行条件过滤或者是单线程的索引扫描,性能很低。

MogDB通过将查询任务分解为多个并行的子任务,同时扫描多个索引,可以避免扫描全部数据文件,提高查询效率,加快数据访问速度。使用并行索引扫描特性可以预计获得大约25%左右的性能提升,而对于整体执行来说,预计可以获得大约10%左右的性能提升。

Mogdb性能增强之并行索引扫描 索引并行扫描原理:

  • 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存储类型。

参考文档

docs.mogdb.io/zh/mogdb/v5… docs.mogdb.io/zh/mogdb/v5…

本文由mdnice多平台发布