Mysql 优化 MIN、MAX 和 SUM 的索引开销

Posted

技术标签:

【中文标题】Mysql 优化 MIN、MAX 和 SUM 的索引开销【英文标题】:Mysql optimize index overhead for MIN, MAX and SUM 【发布时间】:2021-11-16 16:48:32 【问题描述】:

我正在尝试优化我的表格和查询,但没有找到任何解决方案。

表格大小:2246096 行

查询:

SELECT
    MIN(id) AS first_id,
    MAX(id) AS last_id,
    column_1,
    column_2,
    column_3,
    SUM(column_4 + column_5) AS total_4_5,
    SUM(column_6 + column_7) AS total_6_7,
    SUM(column_8 + column_9) AS total_8_9,
    SUM(column_10 + column_11) AS total_10_11
FROM table WHERE
    created_at BETWEEN '2021-10-01 07:45:00' and '2021-11-01 07:44:59'
    OR `id` IN (1,2,3,4,5,6,7...)
GROUP BY
    column_1, column_2;  

在所有列上使用单个索引,查询运行良好,但我的开销非常大。

Data 2.9 GiB
Index 6.3 GiB
Overhead 514.0 MiB
Effective 8.7 GiB
Total 9.2 GiB

有没有其他方法可以在不为所有列添加索引的情况下获取最小值、最大值、列和总和?

感谢您的帮助。

【问题讨论】:

"only_full_group_by" -- 你不应该在GROUP BY 中包含column_3 吗? 您确定OR 吗? WHERE 子句没有多大意义。请用不同的词来形容它。 我们可以删除 OR 子句...但是从我测试的或 id IN 的测试来看,它的工作速度非常快。我向您展示了完整的查询,但也没有 OR 条件,结果是相同的。 【参考方案1】:

在许多情况下,OR 会导致优化失败。通常我建议使用UNION 作为性能解决方法。但是,由于SUMs,这很难做到。

created_at BETWEEN '2021-10-01 07:45:00' and '2021-11-01 07:44:59'
OR `id` IN (1,2,3,4,5,6,7...)

( SELECT ...
    WHERE created_at >= '2021-10-01 07:45:00'
      AND created_at  < '2021-10-01 07:45:00' + INTERVAL 1 MONTH
GROUP BY ... )
UNION ALL
( SELECT ...
    WHERE `id` IN (1,2,3,4,5,6,7...)
      AND NOT (
                created_at >= '2021-10-01 07:45:00'
            AND created_at  < '2021-10-01 07:45:00' + INTERVAL 1 MONTH
GROUP BY ... )

需要的索引:

PRIMARY KEY(id)  -- I assume you have this
INDEX(created_at)

【讨论】:

如上所述,OR 条件不是我的问题。如果我不在主索引中添加 select 中的所有列,我将无法缩短时间。

以上是关于Mysql 优化 MIN、MAX 和 SUM 的索引开销的主要内容,如果未能解决你的问题,请参考以下文章

mysql中min和max查询优化

26《MySQL 教程》聚合函数(聚合函数 MIN、MAX)

告诉我为啥使用“max,min,sum=arr[0];”这段代码

MySQL:优化查询

Excel中的max、min或sum结果总是0,怎么办

Hive分析窗口函数 SUM,AVG,MIN,MAX