MySQL索引设计核心注意事项

索引是MySQL优化的核心,但设计不当会导致查询变慢、写入卡顿、空间浪费 。下面按最实用、最容易踩坑的维度整理,直接用于业务开发。


一、基础原则:什么时候该建索引?

1. 必须建索引的场景

  • WHERE 条件频繁使用的列(等值查询、范围查询)
  • JOIN 关联条件列(内外键都建议建索引)
  • ORDER BY / GROUP BY 排序列
  • DISTINCT 去重列
  • 覆盖查询(查询只返回索引列,不用回表)

2. 绝对不要建索引的场景

  • 列值重复率极高(性别、状态0/1,区分度<20%)
  • 数据量极小(百行以内)
  • 频繁修改、极少查询的表(写入性能会暴跌)
  • 单独的大字段(text、blob、长varchar)

二、最关键:联合索引设计规则(70%的坑都在这)

1. 最左前缀原则(必须死记)

联合索引 (a, b, c) 能命中的查询:

  • where a=?
  • where a=? and b=?
  • where a=? and b=? and c=?

不能命中

  • where b=?
  • where c=?
  • where a=? and c=?(只能命中a,b断层)

2. 联合索引顺序口诀

等值在前,范围在后;区分度高在前,低在后

  • 第1列:高频等值查询(=、in)
  • 第2列:次高频条件
  • 最后一列:范围查询(> < between like)

错误示例:
idx(created_time, status) (范围在前,索引失效)

正确示例:
idx(status, created_time)

3. 控制联合索引列数

建议 2~4列 最佳

列越多:索引体积越大、写入越慢、优化器越难选择。


三、索引字段设计规范

  1. 优先使用小数据类型

    int < bigint,tinyint < int,short string < long string

    索引越小,内存命中率越高,速度越快。

  2. 禁止在索引列上做计算/函数操作

    会导致索引完全失效

    ❌ 错误:where YEAR(create_time)=2025

    ✅ 正确:where create_time >= '2025-01-01'

  3. 字符串必须加长度前缀索引

    避免整字符串建索引,浪费空间

    sql 复制代码
    -- 只索引前10个字符
    create index idx_username on user(username(10));
  4. 允许 NULL 的列不适合建索引

    NULL 会让索引效率下降,建议用默认值(空字符串/0)替代。


四、查询与索引匹配注意事项

  1. like 以通配符开头会失效

    where name like '%张三'

    where name like '张三%'

  2. 隐式类型转换会导致索引失效

    字符串列传数字、数字列传字符串

    where phone=13800138000(phone是varchar)

    where phone='13800138000'

  3. or 连接会导致索引失效

    or 前后必须全部有索引 ,否则全表扫描

    尽量用 union all 替代。

  4. not in / != / is not null 容易导致索引失效

    尽量避免,或改用范围查询。


五、写入性能:索引不是越多越好

  • 每增一个索引,insert/update/delete 就多一次索引维护
  • 单表索引数量建议:3~5个以内
  • 频繁写入的表:少建索引
  • 读多写少的表:可以合理建索引

六、高级优化:覆盖索引(性能神器)

查询的字段 = 索引字段,不需要回表查数据行。

示例:

sql 复制代码
-- 索引
idx(status, created_time, nickname)

-- 查询直接从索引返回,无需回表
select nickname from user 
where status=1 and created_time>'2025-01-01'

覆盖索引能让查询速度提升 5~100倍


七、必须避免的反模式(高频坑)

  1. 单表建十几个索引 → 写入卡死
  2. 每个字段单独建索引 → 优化器无法选择,查询变慢
  3. 联合索引顺序乱排 → 最左前缀失效
  4. 大字段建索引 → 空间爆炸
  5. 低区分度列建索引(性别、状态)→ 索引无用
  6. 查询条件用函数/运算 → 索引直接失效

八、索引维护与检查

  1. explain 检查是否命中索引
  2. 删除重复、冗余、从未使用的索引
  3. 大表加索引要在低峰期执行
  4. 定期优化表(optimize table)

总结

  1. 最左前缀是联合索引的灵魂
  2. 等值在前,范围在后
  3. 索引列不计算、不函数、不隐式转换
  4. 单表索引不超过5个
  5. 优先覆盖索引,避免回表
相关推荐
麻瓜生活睁不开眼2 小时前
Android16修改全局桌面视图边框四直角显示为弧边圆角
android·java·深度学习
三十岁老牛再出发2 小时前
07.27&7.28每日总结
c语言·mysql
dear_bi_MyOnly2 小时前
【MyBatis 操作数据库】
java·数据库·学习·mybatis·学习方法
DBA_G3 小时前
南大通用GBase 8s数据库新存储引擎核心能力二
数据库·微服务·架构
衣乌安、5 小时前
数据库事务原理与回滚机制
数据库
AFinalStone5 小时前
Android 7系统休眠唤醒(六)唤醒全链路
android·电源管理·休眠唤醒
CodexDave6 小时前
PostgreSQL 明明有索引却选了 Nested Loop:从行数误判修正执行计划
数据库·postgresql·执行计划·扩展统计·nestedloop
雨白6 小时前
深入理解 Kotlin 协程 (九):互通有无,解构 Channel 缓冲策略与底层无锁机制
android·kotlin
czhaii7 小时前
STC ai助手单片机工程项目创建实例
数据库·mongodb
山峰哥8 小时前
数据库性能救星:Explain执行计划深度拆解
服务器·开发语言·数据库·sql·启发式算法