Oceanbase查询改写:集合语句优化

概述

集合语句(union,intersect,except)通常涉及多张表的查询,执行开销往往较大。为此,Oceanbase中定义了相应的集合语句优化规则,能够对满足条件的集合语句进行优化,提升查询性能。

基本原理

集合语句优化规则主要包含对以下两种情况的处理:

  1. order by消除:当集合语句中的子查询中存在order by表达式而没有limit表达式时,移除order by表达式。

  1. limit & orderby & distinct下推:当父查询使用的表达式为union时,如果父查询中包含order by和limit,则可以将表达式下推到子查询;如果父查询的表达式包含distinct语义(非union all)时,则将distinct下推到子查询中。

order by消除

考虑如下情况:

SELECT c1 FROM t1 ORDER BY c1 UNION ALL SELECT c1 FROM t2 ORDER BY c1

对于上述集合语句的子查询而言,即使各自进行了排序,最终union的结果仍然无法保证有序。而由于子查询中没有limit表达式,所以无法在子查询执行阶段各自进行结果裁剪,因此这里的order by没有实际意义,可以被移除,如下所示:

SELECT c1 FROM t1 UNION ALL SELECT c1 FROM t2

limit & orderby & distinct下推

考虑如下情况:

SELECT c1 FROM t1 UNION SELECT c1 FROM t2 ORDER BY c1 limit 10

对于上述子查询而言,如果将父查询中的ORDER BY和limit表达式下推至子查询中,则可以在子查询执行阶段进行结果裁剪,避免产生大量的中间结果。另外,由于UNION操作本身包含了distinct语义,因而可以将distinct下推到子查询中,如下所示:

SELECT DISTINCT c1 FROM t1 ORDER BY c1 limit 10 UNION 
    SELECT DISTINCT c1 FROM t2 ORDER BY c1 limit 10

代码解析

集合语句优化规则的入口为ObTransformSetOp::transform_one_stmt,该函数的主要执行流程如下:

  1. 调用remove_order_by_for_set函数对集合语句的子查询进行order by消除。

  1. 调用add_limit_order_distinct_for_union函数对union语句执行表达式下推。

add_limit_order_distinct_for_union函数负责将limit/orderby/distinct表达式下推至union语句的子查询,如果union语句存在父查询,则该函数首先将父查询中的limit表达式转移到union语句中。如果下推完成后union语句存在limit表达式,且查询中不包含SQL_CALC_FOUND_ROWS表达式,则可以执行下推,执行流程如下:

  1. 调用add_distinct函数将distinct下推至子查询。

  1. 调用add_limit函数将limit表达式下推至子查询。

  1. 调用add_order_by函数将order by表达式下推至子查询。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值