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 NULLAND active=1够吗? 基本上我想要未删除的特定日期的活动框架列表。 但是可以删除活动帧吗?通常当删除记录应该得到active = 0 或者如果不是 - 那你为什么需要active=1 来检查? 【参考方案1】:

查询看起来不错。您所能做的就是提供适当的索引。这至少是WHERE 子句中列的索引。从最严格的列开始。所以,

有多少行匹配active = 1? 有多少行匹配deletedOn IS NULL? 有多少行匹配updatedOn &lt;= 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的SQL语句优化-group by语句的优化

MySQL使用group by 报this is incompatible with sql_mod

sql查询出现1055 this is incompatible with sql_mode=only_full_group_by