MySQL 查询优化 Group By with Max
Posted
技术标签:
【中文标题】MySQL 查询优化 Group By with Max【英文标题】:MySQL Query Optimization Group By with Max 【发布时间】:2019-08-16 06:51:35 【问题描述】:尝试优化使用 Group by 和 Max 的 mysql 查询。尝试获取在任何过去日期之前处于活动状态的最新更新帧。
审核框架表结构:
id bigint pk AI
frame_id bigint fk
name VARCHAR(50)
active int
createdOn DATETIME
updatedOn DATETIME
deletedOn DATETIME
id、frame_id 和 updatedOn 有单独的索引..
当前查询:
SELECT MAX(id) as id1
FROM audit_frame_master
WHERE updatedOn <='2019-03-25 21:00:00'
AND active=1
AND deletedOn IS NULL
GROUP
BY frame_id
性能:
表格有大约 1M 行。执行平均需要 4 秒。有没有办法优化上述查询?
下面是相同的 EXPLAIN 语句。
【问题讨论】:
你的集群索引列是什么? @SiamakFerdos: id 是集群索引列。 为什么你需要两个AND active=1 AND deletedOn IS NULL
? AND active=1
够吗?
基本上我想要未删除的特定日期的活动框架列表。
但是可以删除活动帧吗?通常当删除记录应该得到active = 0
或者如果不是 - 那你为什么需要active=1
来检查?
【参考方案1】:
查询看起来不错。您所能做的就是提供适当的索引。这至少是WHERE
子句中列的索引。从最严格的列开始。所以,
active = 1
?
有多少行匹配deletedOn IS NULL
?
有多少行匹配updatedOn <= timestamp '2019-03-25 21:00:00'
?
选择行数最少的那个。说是active
,然后是updatedOn
,然后是deletedOn
。这给了你:
create index idx on audit_frame_master(active, updatedOn, deletedOn);
如果您想按frame_id
分组,然后找到最大的id
,您可以按此顺序添加:
create index idx on audit_frame_master(active, updatedOn, deletedOn, frame_id, id);
这是一个覆盖索引。如果 DBMS 使用它,它甚至不必访问表。
DBMS 可能使用也可能不使用此索引。这只是一个提议。如果 DBMS 认为通过索引而不是简单地按顺序读取表将需要太多工作,那么它就不会使用它。试试吧。
【讨论】:
我添加了这些索引,似乎性能有所改善,但仍然没有那么快。是因为 updatedOn 和 deletedOn 是 DateTime 并且需要更多的计算时间吗? 不,没关系。这只是很多工作要做。单独的条件有多少行,组合的条件有多少?表格中有多少不同的帧,结果中有多少? 请看我编辑的问题。我附上了解释声明。 我不知道如何阅读 MySQL 解释计划。我是否正确地看到WHERE
子句保留了超过 10% 的表行?那么 DBMS 并没有从索引中获得太多好处。需要对大量数据进行排序和汇总。
是的,在某些情况下,它可能有超过 10% 的表行。在这种情况下,您是否建议更改任何特定的数据库表?【参考方案2】:
添加以下复合索引:(frame_id, active, deletedOn, updatedOn, id)
并报告其执行情况。
【讨论】:
没有更多的视觉改进..@Willem【参考方案3】:你不想
SELECT frame_id, MAX(id)
而不是
SELECT MAX(id)
??
这可能是最佳索引。请注意它如何首先列出 WHERE
列,假设过滤比分组更重要:
INDEX(active, deletedOn, -- in either order
updatedOn)
添加frame_id, id
(以任意顺序,但在最后)会将其变成“覆盖”索引,从而获得更快的速度。
【讨论】:
以上是关于MySQL 查询优化 Group By with Max的主要内容,如果未能解决你的问题,请参考以下文章
MySQL调优--05---多表查询优化子查询优化 ORDER BY优化GROUP BY优化分页查询优化
使用 GROUP BY ... HAVING 优化 MySQL 查询时遇到问题
具有 JOIN 和 GROUP BY 优化的 MySQL 查询。是不是可以?
MySQL使用group by 报this is incompatible with sql_mod
sql查询出现1055 this is incompatible with sql_mode=only_full_group_by