mysql索引是否越多越好_mysql设计误区解析

6次阅读

索引并非越多越好,反而会拖慢写入操作、占用资源并干扰优化器选择;低基数字段、重复前缀、仅用于 ORDER BY 或 LIKE ‘%xxx’ 的索引往往无效;应通过 EXPLAIN 和 sys.schema_unused_indexes 验证索引实际使用情况,并在建索引前评估查询频率、复用性和替代方案。

mysql 索引是否越多越好_mysql 设计误区解析

索引越多,查询越快?别信这个直觉

不是。索引本身不加速所有查询,反而在写入时强制增加开销,且会显著拖慢 INSERTUPDATEDELETE 操作。MySQL 每次修改数据,都要同步更新对应索引的 B+ 树结构——索引越多,维护成本越高。

更关键的是:无效索引会持续占用内存和磁盘空间,影响 Buffer Pool 利用率,甚至导致执行计划误判(比如优化器因索引过多而选错 key)。

哪些索引大概率是“假有用”?

以下几类索引常被误建,实际几乎不被优化器选用:

  • status 这类低基数字段(如只有 'active'/'inactive')单独建索引,MySQL 通常直接走全表扫描,因为回表代价可能比扫一遍还高
  • 重复前缀的联合索引,例如已有 (user_id, created_at),又额外建了 (user_id) —— 后者完全被前者覆盖
  • 只在 ORDER BY 中出现、却不在 WHERE 条件里的字段索引(如 ORDER BY updated_at 但无 WHERE updated_at > ?),除非配合 LIMIT 且数据量极小,否则基本无效
  • 频繁 LIKE '%xxx' 模糊查询的字段建普通 B-Tree 索引,根本用不上

怎么判断一个索引是否真被用了?

别靠猜,用 EXPLAINinformation_schema.STATISTICS 交叉验证:

  • 执行 EXPLAIN SELECT ……,重点看 key 列是否显示该索引名,以及 rows 是否明显下降
  • sys.schema_unused_indexes(MySQL 8.0+)或手动统计 performance_schema.table_io_waits_summary_by_index_usage,确认该索引自启动后 COUNT_STAR = 0
  • 注意:即使 EXPLAIN 显示用了某个索引,也要结合 type 值判断——如果是 indexALL,说明只是扫描索引树或全表,并非高效查找
SELECT * FROM sys.schema_unused_indexes  WHERE object_schema = 'your_db' AND object_name = 'your_table';

建索引前必须问的三个问题

每加一个索引,都该明确回答:

  • 这个查询是否高频?低频查询不值得用写入代价换读取收益
  • 这个索引能否支撑多个查询?优先建能复用的联合索引(按 WHERE 等值 → INORDER BY 字段顺序 排列
  • 有没有更轻量的替代?比如把 JSON 字段拆成普通列再索引,或用生成列(GENERATED COLUMN)+ 索引替代复杂表达式查询

真正难的不是“怎么建索引”,而是“为什么 这里不该建”。线上表一旦有千万级数据,删一个无用索引都可能锁表几分钟——设计阶段多花十分钟想清楚,后期省的不止是磁盘和 CPU。

星耀云
版权声明:本站原创文章,由 星耀云 2026-01-06发表,共计1255字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources