VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

ROWNUM查询性能优化

功能描述

ROWNUM查询优化为LIMIT节点,提升执行效率。原始ROWNUM查询在执行时会整表扫描,然后再判断ROWNUM的条件,执行效率较低,对于特定场景优化为LIMIT节点可以提前结束执行,以提高执行效率。

注意事项

  • 仅Vastbase V2.2 Build 10(Patch No.17)及以后版本支持此功能。

  • 仅支持 1 <= ROWNUM and ROWNUM < k的场景。

  • 支持嵌套一层的子查询,不支持多层嵌套子查询。

  • 由于语法限制,该特性仅在数据库兼容模式为Oracle时支持(即数据库初始化时指定DBCOMPATIBILITY='A')。

  • 如原语句中已有LIMIT,则不支持ROWNUM再改为LIMIT,会导致语义冲突。

  • 不支持带有AGG SORT的场景进行优化。

示例

1、创建测试表并插入测试数据。

CREATE TABLE my_table_1219197(id int, stuname varchar(10));
INSERT INTO my_table_1219197 VALUES(1, 'stu1'),(2, 'stu2'),(3, 'stu3'),(4, 'stu4'),(5, 'stu5'),(6, 'stu6'),(7, 'stu7'),(8, 'stu8'),(9, 'stu9'),(10, 'stu10');

2、查看执行计划。

EXPLAIN ANALYZE SELECT id FROM my_table_1219197 WHERE rownum < 3 UNION SELECT id FROM (SELECT id FROM my_table_1219197 ORDER BY 1) WHERE rownum < 5;

返回结果为:

                                                              QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------
 HashAggregate  (cost=79.04..79.10 rows=6 width=4) (actual time=0.065..0.066 rows=4 loops=1)
   Group By Key: public.my_table_1219197.id
   ->  Append  (cost=0.00..79.02 rows=6 width=4) (actual time=0.019..0.045 rows=6 loops=1)
         ->  Limit  (cost=0.00..0.04 rows=2 width=4) (actual time=0.018..0.019 rows=2 loops=1)
               ->  Seq Scan on my_table_1219197  (cost=0.00..21.34 rows=1134 width=4) (actual time=0.016..0.017 rows=2 loops=1)
         ->  Limit  (cost=78.87..78.92 rows=4 width=4) (actual time=0.021..0.022 rows=4 loops=1)
               ->  Sort  (cost=78.87..81.71 rows=1134 width=4) (actual time=0.021..0.022 rows=4 loops=1)
                     Sort Key: public.my_table_1219197.id
                     Sort Method: top-N heapsort  Memory: 25kB
                     ->  Seq Scan on my_table_1219197  (cost=0.00..21.34 rows=1134 width=4) (actual time=0.002..0.003 rows=10 loops=1)
 Total runtime: 0.275 ms
(11 rows)

如执行计划所示,ROWNUM查询扫描通过Limit节点而非全表扫描。

3、清理测试数据。

DROP TABLE my_table_1219197;