MySQL索引完全指南:让你的查询速度飞起来

以下是 2025–2026 年视角下 MySQL 索引的完整、实用指南(基于 MySQL 8.0 ~ 8.4 主流版本 + InnoDB 引擎)。

内容结构化、带代码示例、常见误区、优化 checklist 和真实案例,目标是让你读完就能真正把查询速度提起来,而不是只停留在“知道 B+ 树”层面。

一、为什么索引能让查询“飞起来”?核心原理(B+ 树 vs B 树)

项目B 树(经典)B+ 树(InnoDB 实际使用)为什么 B+ 树更快?
叶子节点存数据是(所有节点都存数据)只叶子节点存数据,非叶子只存键同一层级能放更多键,树更矮
叶子节点是否链表是(双向链表)范围查询顺序扫描极快
范围查询效率中等极高顺序 I/O 而非随机 I/O
扇出(fan-out)较低极高(一页 16KB 可存数百~上千键)层级少 → 查找次数少
InnoDB 页大小默认 16KB

一句话总结
InnoDB 用 B+ 树 + 数据页 + 双向链表 + 自适应哈希索引(adaptive hash index)组合,让 等值 + 范围 + 排序 + 覆盖 查询都非常高效。

二、MySQL 主流索引类型对比(2025–2026 现状)

索引类型底层结构支持操作典型场景InnoDB 支持MyISAM 支持备注 / 限制(MySQL 8.4)
主键索引B+ 树=, >, <, BETWEEN, IN, ORDER BY每张表必须有(聚簇索引)必须 NOT NULL + UNIQUE
唯一索引B+ 树同上邮箱、手机号、订单号等允许 NULL(但 NULL 不重复)
普通索引B+ 树同上where、order by、group by 高频列
复合索引B+ 树最左前缀匹配多条件组合查询遵循最左前缀原则
全文索引倒排索引MATCH AGAINST文章搜索、商品标题模糊搜索是(ngram / MeCab)InnoDB 5.6+ 支持
空间索引R 树ST_Contains, ST_Within 等GIS、地图附近查询是(5.7+)必须 GEOMETRY 类型
哈希索引哈希表=, <=>MEMORY 引擎等值查询不直接支持(有自适应哈希)InnoDB 自适应哈希内部使用
函数索引(8.0+)B+ 树对函数/表达式建索引UPPER(name)、JSON_EXTRACT 等非常实用
降序索引(8.0+)B+ 树(逆序)ORDER BY DESC 优化按时间倒序分页减少 filesort
不可见索引(8.0+)B+ 树(隐藏)测试新索引效果,不影响现有查询计划安全上线神器

三、创建索引的正确姿势(推荐写法)

-- 1. 主键(自动创建聚簇索引)
CREATE TABLE users (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    ...
);

-- 2. 普通单列索引
CREATE INDEX idx_email ON users(email);

-- 3. 唯一索引
CREATE UNIQUE INDEX uk_phone ON users(phone);

-- 4. 复合索引(最左前缀原则顺序非常重要)
CREATE INDEX idx_name_age_city ON users(name, age, city);

-- 5. 覆盖索引(查询字段全在索引中,无需回表)
CREATE INDEX idx_cover ON orders(user_id, order_time, amount);

-- 6. 函数索引(MySQL 8.0+)
CREATE INDEX idx_upper_name ON users((UPPER(name)));

-- 7. 降序索引(8.0+)
CREATE INDEX idx_time_desc ON orders(create_time DESC);

-- 8. 全文索引(ngram 适合中文)
CREATE FULLTEXT INDEX ft_title_content ON articles(title, content) WITH PARSER ngram;

-- 9. 空间索引
CREATE TABLE locations (
    id INT AUTO_INCREMENT PRIMARY KEY,
    coord POINT NOT NULL SRID 4326,
    SPATIAL INDEX idx_coord(coord)
);

四、复合索引最左前缀原则(最容易踩的坑)

规则:复合索引 (a,b,c) 能用到的查询条件必须从 最左边开始连续匹配

查询条件是否走索引 (idx_a_b_c)能用到的索引部分说明
WHERE a=1a最左匹配
WHERE a=1 AND b=2a,b连续最左
WHERE a=1 AND c=3ab 断开,c 无法用
WHERE b=2不符合最左
WHERE a>1 AND b=2是(a 范围,b 等值)a,b范围后等值仍可
WHERE a=1 ORDER BY b,ca,b,c排序也能用
WHERE a=1 ORDER BY c部分(a 用索引,c filesort)a

黄金经验:把频率最高、最有区分度的列放最左

五、覆盖索引 & 回表(性能差距可达 5~20 倍)

  • 回表:查了索引,但要再去聚簇索引取整行数据 → 额外一次 IO
  • 覆盖索引:查询的所有字段都在索引中(包括 SELECT、WHERE、ORDER BY),无需回表

经典案例

-- 慢(回表)
SELECT id, name, create_time FROM users WHERE phone = '13812345678';

-- 快(覆盖)
CREATE INDEX idx_phone_name_time ON users(phone, name, create_time);
SELECT id, name, create_time FROM users WHERE phone = '13812345678';

六、2025–2026 高频索引失效场景(带解决方案)

失效场景原因解决方案(MySQL 8.0+)
LIKE ‘%xx%’最左通配符用全文索引 / ngram / 业务前缀搜索
函数/运算 (WHERE YEAR(create_time)=2025)破坏索引列完整性创建函数索引 / 添加计算列 + 索引
类型隐式转换 (WHERE phone = 138…)varchar 与 int 比较转字符串统一类型,WHERE phone = ‘138…’
OR 条件两边索引不一致优化器放弃索引拆成 UNION ALL 或都建索引
!= / NOT IN / IS NOT NULL选择性低或无法范围扫描业务改为正向查询 / IS NULL 用得少
索引列上用了 != / < > 等部分场景仍可,但选择性低时弃用评估区分度
联合索引跳跃使用不符合最左前缀调整列顺序或拆索引

七、索引优化 checklist(生产必查)

  1. 单表索引个数 ≤ 5~7 个(超过容易选错索引 + 写性能下降)
  2. 每张表必须有主键(InnoDB 聚簇索引)
  3. 区分度低的列(如 gender、status)不要单独建索引
  4. 频繁更新的列慎建索引(写性能下降明显)
  5. 复合索引字段顺序:高频 where → 高区分度 → 排序字段 → 覆盖字段
  6. 优先建覆盖索引
  7. EXPLAIN + typekeyrowsExtra 判断
  • type: ref / eq_ref / range / index 好;ALL / index 坏
  • Extra: Using index(覆盖)好;Using filesort / Using temporary 坏
  1. 大表加索引用 pt-online-schema-change / gh-ost(在线 DDL)
  2. 开启慢查询日志 + long_query_time=1 + log_queries_not_using_indexes=1
  3. 定期用 ANALYZE TABLE / OPTIMIZE TABLE 更新统计信息

八、真实案例对比(速度提升倍数)

场景原 SQL / 索引优化后索引 / SQL速度提升
用户手机号查信息phone varchar(20), 无索引INDEX(phone)几百~几千倍
订单按用户+时间范围WHERE user_id=1 AND create_time BETWEENINDEX(user_id, create_time)10~50 倍
商品标题模糊搜索LIKE ‘%iPhone%’FULLTEXT(title) + MATCH AGAINST几十~几百倍
按创建时间倒序分页ORDER BY create_time DESC LIMIT 10,10INDEX(create_time DESC)避免 filesort
JSON 字段查询JSON_EXTRACT(data,’$.status’)=1生成列 + 索引 或 函数索引10~100 倍

如果你当前有慢查询 SQL、EXPLAIN 输出、表结构,可以贴出来,我帮你现场分析 + 给出最优索引方案。

想深入哪个部分?

  • EXPLAIN 字段逐个详解
  • 聚簇 vs 非聚簇索引内存布局
  • 自适应哈希索引原理
  • 全文索引 ngram vs MeCab(中文场景)
  • 大表加索引在线方案(gh-ost / pt-osc)

随时说~

文章已创建 3890

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部