MySQL慢查询优化求助:千万级jobs表查询耗时20秒,期望降至1秒内
MySQL慢查询优化建议
当前查询耗时过长的核心原因是现有联合索引顺序不符合最左匹配原则,索引利用率极低,需要扫描大量行后还要做额外排序。以下是可落地的优化方案:
方案1:调整联合索引顺序(成本最低,效果最优)
现有索引idx_queue的顺序为scheduled_at, assigned_worker_id, is_deleted,违背了MySQL联合索引「等值过滤条件前置,范围/排序条件后置」的使用规则:
- 查询中
is_deleted = false、assigned_worker_id is null都是等值过滤条件,应该放在索引最左侧 - 范围查询+排序用到的
scheduled_at字段放在最后即可
执行以下语句调整索引:
drop index idx_queue on jobs; create index idx_queue on jobs (is_deleted, assigned_worker_id, scheduled_at);
调整后效果:
- 索引可以直接命中所有三个where过滤条件,不需要额外扫行过滤
- 索引本身已经按
scheduled_at升序排列,无需额外做filesort排序 - 仅需要扫描符合条件的前10行即可返回结果,耗时可降到毫秒级,完全满足1秒以内的要求
如果业务确实需要返回表中所有字段,可以把需要查询的字段追加到索引末尾做成覆盖索引,避免回表查询主键数据,进一步提升性能:
create index idx_queue_covering on jobs (is_deleted, assigned_worker_id, scheduled_at, id, customer_id, description);
方案2:汇总表方案(当前在用方案补充优化)
你目前使用的unassigned_jobs汇总表方案本身是可行的,更适合读请求远多于写请求的业务场景,只需要补充数据同步机制保证数据一致性即可:
- 可以在jobs表上新增增删改触发器,当
assigned_worker_id或者is_deleted字段变更时自动同步数据到汇总表 - 对数据实时性要求不高的场景,也可以用定时任务+增量同步的方式定期补全数据
其他辅助优化点
- 尽量避免使用
select *,仅查询业务需要的字段,减少数据传输和IO消耗 - 如果业务允许,可将UUID类型的主键替换为自增主键,降低索引体积、进一步提升整体查询性能
内容的提问来源于stack exchange,提问作者Kennon Young
相关产品推荐
相关产品推荐

