Oceanbase查询改写:外连接limit下推

概述

当查询语句中包含连接操作时,执行过程中可能产生较大的中间结果集。为此,Oceanbase中定义了外连接limit下推规则,能够将满足条件的外连接查询中的limit表达式下推至外表视图,提升查询性能。

基本原理

考虑如下情况:

SELECT * FROM t1 LEFT JOIN t2 on t1.c1 = t2.c1 ORDER BY t1.c2 LIMIT 10

对于上述查询,其中的order by和limit表达式只涉及外表,因而可以进行下推改写,如下所示:

SELECT * FROM (SELECT * FROM t1 ORDER BY t1.c2 LIMIT 10) v LEFT JOIN t2 on v.c1 = t2.c1 

代码解析

外连接limit下推规则的入口为ObTransformAggregate::transform_one_stmt,执行流程如下:

  1. 调用check_stmt_validity函数检查查询语句是否能够被改写。

  1. 调用do_transform函数执行改写。

check_stmt_validity函数首先会调用check_basic函数对查询语句的基本属性进行检查,能够被改写的语句需要满足如下条件:

  1. 查询语句中不包含distinct、group by表达式、having条件和窗口函数,不涉及半连接。

  1. 查询语句中包含limit表达式。

  1. 查询语句的from表中仅包含一张join表,且该表的类型为必须为左深树(右深树会被转换为左深树)。左深树的左叶子节点为视图表时,查询语句的where条件为空。

对于满足上述条件的查询,该函数会调用check_orderby_and_condition函数收集查询语句中的where条件和order by表达式,然后判断语句中是否存在满足条件的目标外表,执行流程如下:

  1. 调用collect_condition_exprs_table_ids函数收集查询语句中的where条件及涉及的表id。

  1. 调用collect_orderby_table_ids函数收集查询语句中的order by表达式及涉及的表id。

  1. 调用find_target_table函数从join表中找到下推的目标表,该函数会从根节点开始遍历左深树中的左节点。对于每一个树节点,如果其包含的子节点的表id集合与前两步得到的表id的并集相同,说明该节点的左右节点都被包含在where条件或order by表达式中,因此选择该节点作为目标节点。如果根节点满足要求,则说明无法进行下推,因此会退出改写流程。

  1. 调用check_validity_for_target_table函数判断目标节点能够被改写,以及是否需要为其创建视图。如果目标节点为基表或join表,则可以进行改写,且需要创建视图;如果目标节点为视图表,则需要根据如下条件进行进一步判断:

  1. 视图查询中包含order by表达式、limit表达式或者窗口函数时,不能进行改写。

  1. 视图查询为集合语句时,能够进行改写,但需要额外创建视图。

  1. 其他情况,能够进行改写且不需要额外创建视图。

do_transform函数负责执行下推改写,处理流程如下:

  1. 调用remove_and_copy_condition_orderby函数从父查询中移除需要下推的where条件,同时获取拷贝需要下推的order by条件。

  1. 调用ObTransformUtils::create_view_with_table函数为目标节点创建视图。

  1. 调用pushdown_view_table函数将where条件、order by表达式和limit表达式下推到视图表中。

  1. 调用add_condition_expr_for_viewtable函数将where条件下推到视图表中。如果目标表为视图表,则需要更新下推表达式的列依赖。

  1. 调用add_orderby_for_viewtable函数将order by表达式下推到视图表中。如果目标表为视图表,则需要更新下推表达式的列依赖。

  1. 调用add_limit_for_viewtable函数将limit表达式下推到视图表中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值