MySQL含ORDER BY的关联查询性能优化求助:加载10条数据耗时超5秒
优化MySQL带ORDER BY的查询性能
问题分析
你的查询移除ORDER BY后速度骤升,但保留时耗时超5秒,核心原因是MySQL无法利用现有索引高效完成排序,大概率触发了filesort(文件排序)——MySQL需要先筛选出符合条件的数据,再在内存/磁盘中排序,数据量较大时会严重拖慢速度。
具体优化方案
1. 创建精准匹配查询条件的联合索引
针对feedbacks表,创建包含过滤条件和排序字段的联合索引:
CREATE INDEX idx_feedbacks_deleted_carrier_created ON feedbacks (deleted_at, carrier_id, created_at DESC);
deleted_at放在最前:匹配f.deleted_at is null的等值过滤,快速缩小数据范围- 其次是
carrier_id:对应carrier_id in (...)的过滤条件 - 最后是
created_at DESC:让索引本身按created_at倒序排列,MySQL直接从索引中取前10条即可,无需额外排序
2. 移除不必要的表关联
查询中inner join carriers c on c.id = f.carrier_id加上c.id in (...),等价于直接过滤f.carrier_id in (...),完全可以去掉carriers表的关联,减少查询开销:
select * from `feedbacks` f where f.carrier_id in (25619, 25620, 25621, 25637, 25758, 25759, 25760, 25761, 25762, 25763, 25976, 25983, 26459, 26460, 27003, 27006, 27052, 27295, 27325, 27387, 27532, 27533, 27534, 27535, 27536, 27537, 27538, 27541, 27542, 27543) and f.`deleted_at` is null order by f.`created_at` desc limit 10 offset 0
3. 验证索引是否生效
执行EXPLAIN查看查询计划:
EXPLAIN select * from `feedbacks` f where f.carrier_id in (...) and f.`deleted_at` is null order by f.`created_at` desc limit 10 offset 0;
- 查看
key字段,确认是否使用了新创建的idx_feedbacks_deleted_carrier_created - 查看
Extra字段,确保没有Using filesort和Using temporary字样
4. 清理冗余索引(可选)
如果新索引生效,可考虑删除冗余旧索引,比如feedbacks_created_at_index、feedback_test_index——这些索引的功能已被新联合索引覆盖,保留会增加写入时的维护成本。
内容的提问来源于stack exchange,提问作者Alexis R
相关产品推荐
相关产品推荐

