Dan*_*Dan 5 index join order-by mysql-5.7
为什么不能查询#2使用相同的(car_trims.horsepower_peak)索引来优化行作为的排序查询#1?在只有两个查询之间的区别是增加的JOIN在查询#2。
PK: (car_trims.id), 索引(car_trims.horsepower_peak)
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
查询#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 BY和ORDER BY。根据 MySQL 文档,
“在某些情况下,MySQL不能使用索引来解决ORDER BY ... [例如,当] ...查询有不同
ORDER BY和GROUP BY表情。”
查询 #1确实混合GROUP BY,ORDER BY因此理论上不应根据文档使用索引,但我相信如果GROUP BY由于仅从主键中选择并分组了 1 个表而完全忽略了该索引,则这可能不适用。
此外,我的实际原始查询并不像此处提供的示例那么简单。关键区别:GROUP_CONCAT在SELECT要求上述内容GROUP BY中的使用,以防止对所有行进行分组(即获得 1 行结果)。该问题的解决方案是使用DEPENDENT SUBQUERY,如下所述:https : //stackoverflow.com/questions/7381828/indexing-with-group-by-order-by-and-group-concat
查询1:由于id是PRIMARY 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。