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 G100 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;