Oceanbase查询改写:min/max聚合改写

文章介绍了Oceanbase数据库如何通过min/max聚合改写规则提升查询性能。当查询涉及的索引列或常量时,系统会进行特定的改写,避免全表扫描。改写包括索引列聚合和常量聚合两种情况,涉及SQL语句的结构调整和视图的使用。
摘要由CSDN通过智能技术生成
概述

对于单列的min/max聚合,如果参与聚合的列上存在索引,那么不需要实际遍历全表即可得到聚合结果。为此,Oceanbase中定义了min/max聚合改写规则,能够对此类查询语句进行改写,提升查询性能。

基本原理

min/max聚合改写规则主要包含对以下几种情况的处理:

  1. 索引列聚合改写:当查询语句中的min/max聚合函数涉及的列为索引列时,可以进行改写。

  1. 常量聚合改写:当查询语句中的min/max聚合函数涉及的列为常量时,可以进行改写。

索引列聚合改写

考虑如下情况:

SELECT max(c1) FROM t1

对于上述查询,如果参与聚合的列上建有索引,那么可以对其进行改写以避免全表扫描,如下所示:

SELECT max(c1) FROM (SELECT c1 FROM t1 ORDER BY c1 DESC LIMIT 1) v

常量聚合改写

考虑如下情况:

select max(1) FROM t1

对于上述查询,聚合函数涉及的列为常量,可以对其进行改写以避免全表扫描,如下所示:

SELECT max(c) FROM (SELECT 1 AS c FROM t1 LIMIT 1) v

代码解析

min/max聚合改写规则的入口为ObTransformAggregate::transform_one_stmt,执行流程如下:

  1. 调用transform_column_aggregate函数执行索引列聚合改写。

  1. 调用transform_const_aggregate函数执行常量聚合改写。

索引列聚合改写

transform_column_aggregate函数首先会调用is_valid_column_aggregate检查查询语句是否能够被改写,然后调用transform_aggregate函数执行改写。能够被改写的语句需要满足如下条件:

  1. 只包含一张from表,且不能为join表。

  1. select列表中只包含一个非常量的聚合函数列,没有group by表达式。

  1. 聚合函数类型为min/max,且参与聚合的列上存在索引。

  1. having条件中不包含列表达式和子查询表达式。

transform_aggregate函数负责对满足条件的语句执行改写,执行流程如下:

  1. 调用create_stmt函数使用原查询语句创建视图表,将原查询语句提升为父查询。

  1. 调用transform_child_stmt函数对视图表查询进行改写,执行流程如下:

  1. 调用set_child_select_item函数将select列中原来聚合函数列替换成其中包含索引的数据列。

  1. 调用set_child_condition函数在where条件中添加数据列的is not null条件。

  1. 调用set_child_order_item函数根据聚合函数类型设置对应的order by表达式。

  1. 调用set_child_limit_item函数添加limit 1表达式。

  1. 清除聚合项、having条件和窗口函数等。

  1. 调用transform_upper_stmt函数对父查询进行改写,执行流程如下:

  1. 调用set_upper_from_item函数将视图表添加到父查询的from列表中。

  1. 调用set_upper_select_item函数将聚合函数列添加到父查询的select列表中。

  1. 调用clear_unused_attribute函数清除多余的属性(因为子查询中已经包含了)。

常量聚合改写

transform_const_aggregate函数首先会调用is_valid_const_aggregate函数,检查查询语句是否能够被改写,即select列表中是否仅包含一个常量min/max聚合列,如min(1)。如果满足,则根据查询语句的特点,使用如下不同方式进行改写:

  1. 如果包含group by表达式,则用聚合函数内的常量替换聚合函数表达式,然后清除聚合项和order by表达式。

  1. 如果from列表仅包含一张表且为视图表,则在视图语句中添加limit 1表达式。

  1. 其他情况则调用前述transform_aggregate函数执行改写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值