【问题标题】:Is MySQL smart enough to stop considering rows once HAVING condition must be true?一旦 HAVING 条件必须为真,MySQL 是否足够聪明以停止考虑行?
【发布时间】:2018-03-04 14:38:42
【问题描述】:

想象一下这样的查询

SELECT col1
FROM t
GROUP BY col2
HAVING COUNT(col3) > 1;

col2 上有可用索引的地方。当 MySQL 扫描 col2 索引并计算 COUNT(col3) 时,它会在计数超过 1 时立即停止计数并向前扫描到下一个唯一的 col2 值吗?还是会考虑每一行并获得准确的计数,然后在完全汇总后将其与 1 进行比较?

【问题讨论】:

    标签: mysql group-by query-optimization


    【解决方案1】:

    这是有根据的推测。当HAVING 子句为真时,MySQL 不够聪明,无法停止。为什么?因为 MySQL 先执行GROUP BY,然后执行ORDER BY。据我所知,它不会将过滤推入聚合步骤——即使使用索引也是如此。

    让我们忽略SELECT col1,这在此查询中没有意义。

    如果col2/col3 对是唯一的,那么您可能会通过以下方式获得更好的性能:

    SELECT col1
    FROM t
    WHERE EXISTS (SELECT 1
                  FROM t t2
                  WHERE t2.col2 = t.col2 AND t2.col3 <> t.col3
                 );
    

    这将在第一个匹配的 col3 行处停止。如果情况是您确实在检查 NULL 的值 col3,那么:

    SELECT col1
    FROM t
    WHERE EXISTS (SELECT 1
                  FROM t t2
                  WHERE t2.col2 = t.col2 AND t2.col3 IS NOT NULL AND t2.id <> t.id
                 ) AND
          col3 IS NOT NULL;
    

    后两个查询假设您在t(col2, col3) 上有一个索引。

    【讨论】:

      猜你喜欢
      • 2023-02-09
      • 2023-04-02
      • 1970-01-01
      • 2016-03-25
      • 2011-11-09
      • 1970-01-01
      • 1970-01-01
      • 2012-03-30
      • 2013-06-24
      相关资源
      最近更新 更多