MySQL查询优化分组最大

时间:2019-03-25 23:27:17

标签: database database-design group-by query-optimization groupwise-maximum

尝试优化使用Group by和Max的MySQL查询。尝试获取在任何过去日期之前都处于活动状态的最新更新框架。

审核框架表结构:

README

id,frame_id和updatedOn具有单独的索引。

当前查询:

id bigint pk AI
frame_id bigint fk
name VARCHAR(50)
active int
createdOn DATETIME
updatedOn DATETIME
deletedOn DATETIME

性能:

表有大约1M行。平均需要花费4秒钟来执行。是否有任何方法可以优化上述查询?

下面是EXPLAIN语句。 enter image description here

3 个答案:

答案 0 :(得分: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认为要通过索引而不是简单地依次读取表会花费太多精力,那么它将不会使用它。只需尝试。

答案 1 :(得分:0)

添加以下综合索引:(frame_id, active, deletedOn, updatedOn, id)并报告其性能。

答案 2 :(得分:0)

你不想要

 SELECT frame_id, MAX(id)

代替

 SELECT           MAX(id)

??

这可能是最佳索引。请注意,假设过滤比分组更重要,那么它如何首先列出WHERE列:

INDEX(active, deletedOn,   -- in either order
      updatedOn)

frame_id, id(以任意顺序,但在末尾)将其转变为“覆盖”索引,从而提高了速度。