MySQL 使用 INDEX 使用 GROUP BY 优化 ORDER BY,除非您添加 JOIN

Dan*_*Dan 5 index join order-by mysql-5.7

为什么不能查询#2使用相同的(car_trims.horsepower_peak)索引来优化行作为的排序查询#1?在只有两个查询之间的区别是增加的JOIN在查询#2。

car_trims ~50k 行

PK: (car_trims.id), 索引(car_trims.horsepower_peak)

car_makes ~100 行

PK: (car_makes.id)

查询#1

SELECT car_trims.*
FROM car_trims
GROUP BY car_trims.id
ORDER BY car_trims.horsepower_peak DESC
LIMIT 0, 200
Run Code Online (Sandbox Code Playgroud)

执行时间处理时间: .0026 seconds

解释: 查询 #1 解释

查询#2

SELECT car_trims.*
FROM car_trims
STRAIGHT_JOIN car_makes ON car_makes.id = car_trims.make_id
GROUP BY car_trims.id
ORDER BY car_trims.horsepower_peak DESC
LIMIT 0, 200
Run Code Online (Sandbox Code Playgroud)

执行时间处理时间: .2533 seconds

解释: 在此处输入图片说明

更新:

我一直在继续这方面的工作,我相信该指数没有被利用在查询#2,由于混合的GROUP BYORDER BY。根据 MySQL 文档,

“在某些情况下,MySQL不能使用索引来解决ORDER BY ... [例如,当] ...查询有不同 ORDER BYGROUP BY 表情。”

查询 #1确实混合GROUP BYORDER BY因此理论上不应根据文档使用索引,但我相信如果GROUP BY由于仅从主键中选择并分组了 1 个表而完全忽略了该索引,则这可能不适用。

此外,我的实际原始查询并不像此处提供的示例那么简单。关键区别:GROUP_CONCATSELECT要求上述内容GROUP BY中的使用,以防止对所有行进行分组(即获得 1 行结果)。该问题的解决方案是使用DEPENDENT SUBQUERY,如下所述:https : //stackoverflow.com/questions/7381828/indexing-with-group-by-order-by-and-group-concat

Ric*_*mes 1

查询1:由于idPRIMARY KEY,所以它是唯一的。因此,GROUP BY id什么也不做。去掉它。这可能会使其运行得更快。

查询 2 不使用除idfrom以外的任何列car_makes。唯一要做的就是验证make_id car_makes car_makes`JOIN中是否有一行,该步骤可能会消失。car_makes for the . You probably don't need that check, so get rid of in that query. That will simplify things. Note that currently there is a "filesort". Without

至于“为什么它不能使用相同的索引”——STRAIGHT_JOIN强制它首先查看另一个表。这有效地将第二个表变成

WHERE     make_id = ...
GROUP BY  id
ORDER BY  horsepower_peak DESC
Run Code Online (Sandbox Code Playgroud)

为了优化这样的,它必须首先过滤make_id