当前位置: 首页 > news >正文

详解MySQL索引

        索引是 MySQL 性能优化的核心要素之一,合理的索引设计可以大幅提升查询效率。下面我将从索引原理、类型、使用场景到优化策略,系统性地讲解 MySQL 索引。

1. 索引的基本概念

1. 什么是索引?

        索引是存储引擎用来快速查找数据的数据结构,类似于书籍的目录。它通过特定的算法(如B+树)对表中的一列或多列值进行排序存储,从而加速数据检索。

2. 索引的优缺点

  • 优化:

    • 大幅提高查询速度。

    • 加速表连接操作。

    • 保证数据唯一性(唯一索引)。

    • 优化排序和分组操作。

  • 缺点

    • 占用额外存储空间。

    • 降低数据写入速度(增删改需要维护索引)。

    • 增加优化器选择负担。

2. MySQL 索引类型

1. 按数据结构分类

索引类型描述适用场景
B+Tree索引InnoDB默认索引类型,平衡多路搜索树等值查询、范围查询、排序
Hash索引基于哈希表实现,精确匹配效率极高,InnoDB 自动为频繁访问的二级索引创建哈希索引,加速等值查询,完全自动管理,无需配置内存表的等值查询
Full-text全文索引,基于倒排索引实现文本内容的搜索
R-Tree空间索引,用于地理数据GIS数据查询

2. 按功能特性分类

索引类型描述
普通索引最基本的索引,无特殊约束
唯一索引保证列值的唯一性,允许NULL值
主键索引特殊的唯一索引,不允许NULL值,每个表只能有一个
组合索引多个列组合建立的索引
覆盖索引查询的列都包含在索引中,无需回表
前缀索引只对列的前N个字符建立索引,节省空间

3. B+Tree 索引深度解析

1. B+Tree 结构特点

  • 多路平衡查找树:保持数据有序且查询路径长度均衡

  • 非叶子节点只存键值:不存储实际数据,存储索引键值+指针

  • 叶子节点形成链表:便于范围查询和全表扫描

    • 存储索引列的值

    • 对应记录的主键值

    • 事务ID、回滚指针等元数据

    数据只存在叶子节点:保证查询稳定性

2. InnoDB 的 B+Tree 实现

  • 聚簇索引:主键索引的叶子节点存储完整行数据

  • 二级索引:二级索引也称为非聚簇索引,是除主键索引外的所有索引的统称。与聚簇索引(主键索引)不同,二级索引的叶子节点不直接包含完整行数据。非主键索引的叶子节点存储主键值(需要回表查询)。

    • 二级索引的工作机制:

      • 查询流程(回表示例)

        -- 假设有二级索引 idx_name(name)
        SELECT * FROM users WHERE name = '张三';

        执行步骤:

        • 在 idx_name 索引树查找"张三"

        • 找到对应的主键值(如 id=5)

        • 用主键值到聚簇索引查找完整记录

        • 返回所有列数据

      •  覆盖索引优化

        当查询列都包含在二级索引中时,可避免回表:
        -- 索引 idx_name_age(name, age)
        SELECT name, age FROM users WHERE name = '张三';

        此时只需访问二级索引即可获取所需数据。

特性二级索引聚簇索引(主键索引)
存储内容索引列+主键值完整数据行
数量一个表可有多个每个表只有一个
查询方式可能需要回表直接获取数据
叶子节点存储指向主键的引用存储实际数据记录

4. 索引使用最佳实践

1. 索引设计原则

  • 选择性高的列优先:区分度高的列(如ID)比性别更适合建索引

  • 常用查询条件列:WHERE、JOIN、ORDER BY 涉及的列

  • 避免过度索引:一般表不超过5-6个索引

  • 组合索引列顺序:区分度高的列在前,常用查询列在前

2. 最左前缀原则

对于组合索引 (a,b,c):

-- 能使用索引的情况
WHERE a = 1
WHERE a = 1 AND b = 2
WHERE a = 1 AND b = 2 AND c = 3
WHERE a = 1 AND c = 3  -- 部分使用(a)-- 不能使用索引的情况
WHERE b = 2
WHERE c = 3
WHERE b = 2 AND c = 3

3. 索引失效场景

  • 使用函数或运算WHERE YEAR(create_time) = 2023

  • 隐式类型转换WHERE name = 123(name是字符串类型)

  • 前导模糊查询WHERE name LIKE '%张'

  • OR条件不当WHERE a=1 OR b=2(当a、b未都有索引时)

  • 索引列使用NOTWHERE NOT status=1

5. 索引优化技巧 

1. EXPLAIN 分析

Explain详解跳转

EXPLAIN SELECT * FROM users WHERE name = '张三';

关注关键字段:

  • type:从优到差 system > const > eq_ref > ref > range > index > ALL

  • key:实际使用的索引

  • rows:预估扫描行数

  • ExtraUsing index(覆盖索引)、Using filesort(需要额外排序)

2. 索引优化策略

  • 避免SELECT *:只查询需要的列,提高覆盖索引概率

  • 使用索引提示FORCE INDEXUSE INDEX

  • 定期分析表ANALYZE TABLE更新索引统计信息

  • 长字符列使用前缀索引ALTER TABLE t ADD INDEX idx_name(name(10))

6. 特殊索引场景 

1. 覆盖索引优化

-- 创建组合索引
ALTER TABLE orders ADD INDEX idx_user_product(user_id, product_id);-- 查询可以完全使用索引
SELECT user_id, product_id FROM orders WHERE user_id = 100;

2. 索引下推(ICP)

MySQL 5.6+特性,将WHERE条件过滤下推到存储引擎层:

-- 组合索引(a,b)
SELECT * FROM t WHERE a = 'xxx' AND b LIKE '%yyy%';
-- 传统:先回表再过滤b条件
-- ICP:在索引层先过滤b条件再回表

3. MRR优化

多范围读取优化,减少随机IO:

-- 二级索引查询后,按主键排序再回表
SELECT * FROM t WHERE a > 100 AND a < 1000;

7. 索引维护

1. 查看索引信息

SHOW INDEX FROM table_name;

2. 索引碎片整理

-- InnoDB表重建(会锁表)
ALTER TABLE table_name ENGINE=InnoDB;-- 优化表(5.7+在线DDL)
OPTIMIZE TABLE table_name;

3. 索引监控

-- 查看索引使用情况
SELECT * FROM sys.schema_index_statistics;
SELECT * FROM sys.schema_unused_indexes;

8. 总结

        合理设计和使用索引是MySQL性能优化的关键。需要根据实际查询模式、数据分布和业务需求来制定索引策略,并持续监控和调整。记住:最好的索引是那些被实际查询使用的索引,而非数量最多的索引。

相关文章:

  • 使用 uv 工具从 pyproject.toml 和 uv.lock 快速安装 Python 依赖
  • HJ106 字符逆序【牛客网】
  • Leetcode 3313. 查找树中最后标记的节点
  • Pytorch中文文本分类
  • 2025 年油烟净化技术前瞻
  • 车载诊断架构 --- 车载诊断有那些内容(下)
  • mac将自己网络暴露到公网
  • TCP与UDP区别及应用场景详解
  • Gemini 2.5 Pro 一次测试
  • TCP 三次握手,第二次握手报文丢失会发生什么?
  • FFmpeg 安装包全攻略:gpl、lgpl、shared、master 区别详解
  • macOs系统M1芯片执行source ~/.zshrc报错503
  • SurfaceFlinger及Android应用RenderThread角度观察Jank丢帧卡顿
  • 调度关键路径里调整优先级导致hardlockup
  • 5.23本日总结
  • AI编辑器规则
  • 非关系型数据库NoSQL
  • SpringBoot项目中Redis的使用
  • Linux PXE批量装机+无人值守技术(自动化装机)
  • 2025期中考复现
  • 设计网站需要哪些流程/网络工具
  • 怎么授权小说做游戏网站/建站模板哪个好
  • 电子政务网站建设出版社/推广方案策划
  • jsp ajax网站开发典型实例 pdf/百度开户返点
  • 李静做的化妆品网站/免费的推广平台
  • wordpress调用搜索功能/seo课程在哪培训好