Max/Min 函数消除规则
在 SQL 中包含了 /min
函数时,查询优化器会尝试使用 max
/min
消除优化规则来将 max
/min
聚合函数转换为 TopN 算子,从而能够有效地利用索引进行查询。
根据 select
语句中 max
/min
函数的个数,这一优化规则有以下两种表现形式:
当一个 SQL 满足以下条件时,就会应用这个规则:
- 聚合函数没有相应的
group by
语句。
这时 max
/min
消除优化规则会将其重写为:
select max(a) from (select a from t where a is not null order by a desc limit 1) t
这个新的 SQL 语句在 a
列存在索引(或 a
列是某个联合索引的前缀)时,能够利用索引只扫描一行数据来得到最大或者最小值,从而避免对整个表的扫描。
上述例子最终得到的执行计划如下:
存在多个 max/min 函数时的优化规则
- 有多个聚合函数,且所有的聚合函数都是 max/min
- 聚合函数没有相应的
group by
语句。
下面是一个简单的例子:
优化规则会先检查 a
列是否存在索引能够为其保序,如果存在,这个 SQL 会先被重写为两个子查询的笛卡尔积:
这样,两个子句中的 max
/min
函数就可以使用上述“只有一个 max
/min
函数时的优化规则”分别进行优化,最终重写为:
select max_a - min_a
from
(select max(a) as max_a from (select a from t where a is not null order by a desc limit 1) t) t1,
最后得到的执行计划: