Max/Min 函数消除规则

    在 SQL 中包含了 /min 函数时,查询优化器会尝试使用 max/min 消除优化规则来将 max/min 聚合函数转换为 TopN 算子,从而能够有效地利用索引进行查询。

    根据 select 语句中 max/min 函数的个数,这一优化规则有以下两种表现形式:

    当一个 SQL 满足以下条件时,就会应用这个规则:

    • 聚合函数没有相应的 group by 语句。

    这时 max/min 消除优化规则会将其重写为:

    1. 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 函数时的优化规则”分别进行优化,最终重写为:

    1. select max_a - min_a
    2. from
    3. (select max(a) as max_a from (select a from t where a is not null order by a desc limit 1) t) t1,

    最后得到的执行计划: