VastbaseG100

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

Menu

ORDER BY ELIMINATION

功能描述

Vastbase 支持在特定场景下消除不影响最终查询结果的 ORDER BY 子句,从而增强优化器的能力,提高执行效率。启用该功能需设置GUC参数rewrite_rule中包含order_by_elimination取值。

支持场景如下:

  • 查询中带有连接操作(LEFT JOIN、INNER JOIN等),同时不含有rownum表达式,可以消除连接两个子查询中顶层的ORDER BY子句。
  • 查询中存在集合操作(UNION ALL等),同时不包含rownum表达式,可以消除集合两边中顶层的ORDER BY子句。
  • ORDER BY 所在该层查询中,不存在LIMIT子句,不存在DISTINCT ON子句。
  • 外层查询目标列中存在聚集函数,内层查询中的ORDER BY可以进行消除。如存在多层嵌套,更深层的子查询中的ORDER BY也可以进行消除。
  • 子连接中(IN/EXISTS)的ORDER BY可以进行消除。

注意事项

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

  • 在MySQL兼容模式下,如果vastbase_sql_mode中没有设置only_full_group_by,则必须存在分组键才能进行消除。

  • 用户自定义聚集函数由于受输入顺序影响,暂不支持消除ORDER BY。

示例

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

CREATE TABLE t_1219164
(EMPNO NUMBER(4) NOT NULL,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7, 2),
COMM NUMBER(7, 2),
DEPTNO NUMBER(2)
);
INSERT INTO t_1219164 VALUES (1, 'SMITH', 'CLERK', 7902,TO_DATE('17-DEC-1980', 'DD-MON-YYYY'), 800, NULL, 20);
INSERT INTO t_1219164 VALUES (2, 'ALLEN', 'SALESMAN', 7698,TO_DATE('20-FEB-1981', 'DD-MON-YYYY'), 1600, 300, 30);
INSERT INTO t_1219164 VALUES (3, 'WARD', 'SALESMAN', 7698,TO_DATE('22-FEB-1981', 'DD-MON-YYYY'), 1250, 500, 30);
INSERT INTO t_1219164 VALUES (4, 'JONES', 'MANAGER', 7839,TO_DATE('2-APR-1981', 'DD-MON-YYYY'), 2975, NULL, 20);
INSERT INTO t_1219164 VALUES (5, 'MARTIN', 'SALESMAN', 7698,TO_DATE('28-SEP-1981', 'DD-MON-YYYY'), 1250, 1400, 30);
INSERT INTO t_1219164 VALUES (6, 'BLAKE', 'MANAGER', 7839,TO_DATE('1-MAY-1981', 'DD-MON-YYYY'), 2850, NULL, 30);
INSERT INTO t_1219164 VALUES (8, 'CLARK', 'MANAGER', 7839,TO_DATE('9-JUN-1981', 'DD-MON-YYYY'), 2450, NULL, 10);
INSERT INTO t_1219164 VALUES (3, 'SMITH', 'CLERK', 7902,TO_DATE('17-DEC-1980', 'DD-MON-YYYY'), 800, NULL, 20);
INSERT INTO t_1219164 VALUES (2, 'ALLEN', 'SALESMAN', 7698,TO_DATE('20-FEB-1981', 'DD-MON-YYYY'), 1600, 300, 30);
INSERT INTO t_1219164 VALUES (1, 'WARD', 'SALESMAN', 7698,TO_DATE('22-FEB-1981', 'DD-MON-YYYY'), 1250, 500, 30);
INSERT INTO t_1219164 VALUES (8, 'JONES', 'MANAGER', 7839,TO_DATE('2-APR-1981', 'DD-MON-YYYY'), 2975, NULL, 20);
INSERT INTO t_1219164 VALUES (6, 'MARTIN', 'SALESMAN', 7698,TO_DATE('28-SEP-1981', 'DD-MON-YYYY'), 1250, 1400, 30);
INSERT INTO t_1219164 VALUES (4, 'BLAKE', 'MANAGER', 7839,TO_DATE('1-MAY-1981', 'DD-MON-YYYY'), 2850, NULL, 30);
INSERT INTO t_1219164 VALUES (5, 'CLARK', 'MANAGER', 7839,TO_DATE('9-JUN-1981', 'DD-MON-YYYY'), 2450, NULL, 10);

2、查看含有ORDER BY子句的查询原始执行计划。

EXPLAIN(COSTS OFF) SELECT count(*) FROM (SELECT * FROM t_1219164 ORDER BY 1);

返回结果为:

            QUERY PLAN
-----------------------------------
 Aggregate
   ->  Sort
         Sort Key: t_1219164.empno
         ->  Seq Scan on t_1219164
(4 rows)

3、设置参数rewrite_rule,启用ORDER BY ELIMINATION功能,并查看步骤2中的执行计划。

SET rewrite_rule='order_by_elimination,magicset';

EXPLAIN(COSTS OFF) SELECT count(*) FROM (SELECT * FROM t_1219164 ORDER BY 1);

返回结果为:

         QUERY PLAN
-----------------------------
 Aggregate
   ->  Seq Scan on t_1219164
(2 rows)

对比步骤2和步骤3的执行计划可知,启ORDER BY ELIMINATION功能后执行计划消除了ORDER BY部分。

4、清理测试数据。

DROP TABLE t_1219164;