Oceanbase查询改写:any/all子查询优化

Oceanbase通过any/all子查询优化规则提升查询性能,包括min/max改写和any/all消除。min/max改写将比较运算符的any/all子查询转换为聚合查询,而any/all消除则针对单表达式子查询,简化为普通子查询,从而提高查询效率。
摘要由CSDN通过智能技术生成
概述

默认情况下,对于包含any/all子查询的语句需要按照嵌套的方式进行执行,效率十分低下。为此,Oceanbase中定义了相应的any/all子查询优化规则,能够对满足条件的any/all子查询进行优化,提升查询性能。

基本原理

any/all子查询优化规则主要包含对以下两种情况的处理:

  1. min/max改写:当any/all子查询的表达式类型为比较运算符时,将子查询改写为min/max聚合子查询。

  1. any/all消除:当any/all子查询的内容为单个表达式时,将any/all子查询转换为普通子查询,在simplify规则执行时会消除该子查询。

min/max改写

考虑如下情况:

SELECT * FROM t1 WHERE c1 > ALL(SELECT c1 FROM t2) 

上述例子在默认情况下,需要按照嵌套的方式执行,即对父查询中的每一条记录,都需要判断是否满足子查询中的条件。结合该语句的语义,可以将子查询条件进行如下改写:

SELECT * FROM t1 WHERE c1 > ALL(SELECT max(c1) FROM t2)

经过改写后,子查询被转换成了聚合子查询。在实际执行时,可以将子查询先行聚合,然后将得到的结果用于父查询的过滤,从而大大提升了查询效率。

any/all消除

考虑如下情况:

SELECT * FROM t1 WHERE c1 > ALL(SELECT 100)

上述例子中的子查询为单表达式,可以移除any/all,如下所示:

SELECT * FROM t1 WHERE c1 > (SELECT 100)

在simpify规则执行时,会进一步消除子查询。

代码解析

any/all子查询优化规则的入口为ObTransformSubqueryCoalesce::transform_one_stmt,该函数最终调用do_transform_any_all函数进行优化,执行流程如下:

  1. 调用transform_any_all_as_min_max函数对any/all子查询语句进行min/max改写。

  1. 调用eliminate_any_all_before_subquery函数将单表达式的any/all子查询转化为普通子查询。

transform_any_all_as_min_max函数负责将any/all子查询改写为聚合子查询,能够被改写的子查询需要满足如下条件:

  1. 子查询对应的表达式必须为>,>=,<,<=中的一种。

  1. 子查询必须只包含一个select列,且该列需要属于某个索引前缀。

  1. 如果子查询为all类型,则select列必须为非空列。

该函数最终调用do_transform_any_all_as_min_max函数进行改写,该函数主要将select列替换成对应列的min/max表达式,对于all类型的子查询,需要额外添加having非空条件,如下所示:

having max/min(col) is not null

eliminate_any_all_before_subquery函数负责将单表达式的any/all子查询转换为普通子查询,该函数执行逻辑较为简单,这里不再赘述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值