MySQL 连接的老实指南:索引为什么反而让连接变慢
来源:dev.to — 2026-10-31
📋 概述
例子用两张表:accounts 十万行,orders 两百万行;accounts 的 plan 列上没有索引,而 20% 的账号是 enterprise 计划。查询是统计所有企业计划账号的订单金额总和。两个直觉都会失准:一是有 orders(account_id) 索引,所以一定比没索引快;二是 MySQL 会选更快的执行计划。实际是 MySQL 选中的计划跑了 2.36 秒,而强制忽略索引后同一个查询只要 0.47 秒——索引让连接更慢了。原因是优化器估算行数不准,走上了对被驱动表逐行回表的路径,而全表扫描配合哈希连接在这里更便宜。文章基于 MySQL 8.0.20 及以后版本,因为 8.0.18 与 8.0.20 前后连接行为变化很大。
🔑 核心要点
- 带索引的连接耗时 2.36 秒,忽略索引后降到 0.47 秒:这就是「索引让连接变慢」的具体现场。
- 优化器会误估行数,选到错误的连接顺序:一旦选错,逐行回表的代价会超过一次全表扫描。
- 低选择性的过滤条件把索引变成负担:20% 的账号都是 enterprise 计划,走索引反而更贵。
- 结论只对 MySQL 8.0.20 及以后成立:8.0.18 与 8.0.20 前后的连接行为差别很大。
💡 金句
When I forced MySQL to ignore the indexes, the same query took 0.47 s.
译:当我强制 MySQL 忽略这些索引,同一个查询只花了 0.47 秒。
👍 0
👎 0
← 返回 dev.to 首页