首页/数据/数据库速查/索引设计原则清单
性能与调优57 条

索引设计原则清单

索引设计五问:哪些查询是热点?条件列的选择性?排序/分组列能否顺带覆盖?写放大能接受吗?现有索引能否改造而非新增?

数据库速查数据更新于 2026-10-13

索引设计怎么想

索引设计可以顺着五个问题走:哪些查询是热点、条件列的选择性够不够、排序与分组列能否顺带覆盖、写入放大的代价能否接受、现有索引能不能改造而不是新增。这五个问题覆盖了索引设计最容易出错的地方——问题通常不是缺索引,而是索引建错位置、建得过多,或者与真实查询形态不匹配。

基本信息

核心问题热点查询、选择性、覆盖、写放大、能否改造
列顺序原则等值条件在前,范围条件次之,排序列最后
选择性要求高区分度的列优先
覆盖策略让高频查询只读索引不必回表
数量控制控制单表索引数量以平衡写入代价
清理要求冗余索引定期清理

设计要点

  • 选择性高的列优先:区分度越大过滤效果越好
  • 复合索引按等值条件、范围条件、排序需求的顺序排布
  • 高频查询尽量被单个复合索引完全覆盖,避免回表
  • 控制单表索引数量,写入代价与索引数量成正比
  • 冗余索引定期清理:前缀相同的索引往往可以合并审视

索引现状盘点

索引现状盘点
SELECT INDEX_NAME, GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) AS cols,
       MAX(CARDINALITY) AS card, MAX(NON_UNIQUE) AS non_unique   # 卡片度反映选择性
FROM information_schema.statistics
WHERE TABLE_SCHEMA='appdb' AND TABLE_NAME='orders'
GROUP BY INDEX_NAME;   # 一眼看出各索引包含哪些列、顺序如何

设计对照

场景推荐做法原因
等值加排序复合索引把等值列放前、排序列放后排序可直接借用索引顺序
多条件查询把最常用的组合建成一个复合索引减少索引数量并提升命中率
低选择性列不单独建索引优化器基本不会使用
长字符串列用前缀索引并验证区分度完整索引体积过大
写多读少的表严格控制索引数量每个索引都会拖慢写入
前缀重复的索引合并或删除其中一个冗余索引只增加成本
索引不是越多越好:每个索引都是写入成本与磁盘成本,应按真实查询矩阵设计,而不是凭直觉逐字段添加。
低选择性列单独建索引(例如性别、状态枚举)基本不会带来收益:优化器通常直接放弃使用,只留下空间与写入开销。

设计复核清单

  • 列出热点查询并按耗时排序
  • 核对每个索引是否对应真实语句
  • 检查复合索引的列顺序是否符合最左前缀
  • 评估新增索引带来的写入代价
  • 定期清理冗余与未被使用的索引
索引设计要跟着查询形态演进:业务查询变了而索引没变,就会出现索引闲置与写入变慢同时发生的局面,定期按慢查询清单回看索引是必要动作。

易错点

  • 为每条查询单独建索引:写性能断崖式下跌,索引之间还互相拖累
  • 给低选择性列单独建索引:优化器基本不使用,白占空间还拖慢写入
  • 复合索引列顺序按字段习惯排列:最左前缀用不上,索引实际无效
  • 索引只加不删:冗余索引持续累积,写入变慢且可选空间被干扰

数据来源与参考

  • MySQL 8.0 Reference Manual: Optimization and Indexes

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌