mysql索引设计错误会有什么影响_mysql性能问题分析

来源:这里教程网 时间:2026-02-28 20:51:46 作者:

索引字段顺序错误导致查询完全走不到索引

MySQL 的联合索引遵循最左前缀原则,

WHERE
条件没用上索引最左边的列,后续列基本无效。比如建了
INDEX (a, b, c)
,但查询写成
WHERE b = 1 AND c = 2
,这个索引就无法使用。

实操建议:

把高频过滤、高区分度的字段放在联合索引最左侧
EXPLAIN
key
possible_keys
是否命中预期索引
注意
ORDER BY
GROUP BY
字段是否能被同一索引覆盖,否则可能触发 filesort

在低区分度字段上建索引反而拖慢写入

比如对只有 'Y'/'N' 两个值的

is_deleted
字段单独建索引,MySQL 查询时仍大概率走全表扫描(优化器认为索引选择性太差),而每次
INSERT
/
UPDATE
都要维护额外 B+ 树节点,写性能下降明显。

实操建议:

SELECT COUNT(DISTINCT col) / COUNT(*) FROM table
粗略估算选择性,低于 0.01 就谨慎建单列索引
低区分度字段可考虑和高区分度字段组合成联合索引,让整体选择性提升 避免对
ENUM
TINYINT
类型且取值极少的字段单独建索引

索引过多引发 INSERT/UPDATE 延迟和锁竞争

每多一个索引,插入一行就要同步更新多个 B+ 树,不仅耗 CPU 和 I/O,还会延长行锁持有时间。尤其在高并发写入场景下,容易出现

lock wait timeout
或主从延迟加剧。

实操建议:

SHOW INDEX FROM table_name
定期检查未被使用的索引(配合
performance_schema.table_io_waits_summary_by_index_usage
删除长期
rows_read = 0
的索引
写多读少的表,索引总数控制在 4–5 个以内更稳妥

字符串字段没加前缀长度就建索引

VARCHAR(500)
字段直接建
INDEX (content)
,MySQL 默认会为索引项分配全部 500 字符空间(utf8mb4 下达 2000 字节),导致索引体积暴增、内存占用高、缓存命中率下降,甚至触发
index column too long
报错。

实操建议:

SELECT MAX(LENGTH(col)) FROM table
查真实最大长度,再定前缀长度
英文/数字类字段通常 10–20 足够;中文标题类可设 30–60,但别盲目拉满 前缀索引无法用于
ORDER BY
GROUP BY
,需要排序聚合时得另作权衡
索引不是越多越好,也不是越长越准。真正影响性能的,往往是那个本该存在却缺失的索引,或者那个一直没人查、却每天被更新几十万次的冗余索引。

相关推荐