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 的索引开销的主要内容,如果未能解决你的问题,请参考以下文章
26《MySQL 教程》聚合函数(聚合函数 MIN、MAX)