MySQL索引是加速检索的特殊数据结构,不改变原表而额外建立“目录表”,存字段值及对应行的物理位置;其核心由索引键值和指向数据行的指针组成,查询时先查B+树索引再回表取数。

MySQL索引是一种特殊的数据结构,用来加速数据检索。它不改变原始表内容,而是额外建立一张“目录表”,里面存着某列(或几列)的值,以及这些值对应的数据行在磁盘上的物理位置。
索引就像字典的音序表
查“李四”时,如果没有索引,MySQL就得从第一行开始逐行扫描整张表(全表扫描);有了索引,它先在索引里快速定位到“李四”对应的地址,再直接跳过去取数据——省掉大量I/O,查询可能快几十倍甚至上千倍。
常见类比:书的目录、地图的索引页、电话簿按姓氏排序——都是靠预排序+映射关系实现快速查找。
索引的核心组成和工作方式
一个典型索引包含两部分:
- 索引键值:比如 name = '李四'、user_id = 1001 这样的字段值
- 指向数据行的指针:InnoDB 中通常是主键值(聚簇索引下就是数据本身),MyISAM 中是数据行的磁盘地址
查询时,MySQL先查索引树(主流是B+树),找到匹配键值后,再根据指针取出完整记录——这个过程叫“回表”,除非索引已覆盖全部需要的字段(即覆盖索引)。
常见索引类型及关键区别
按功能与约束分:
- 主键索引:唯一 + 非空,每张表仅一个,InnoDB中自动作为聚簇索引,决定数据物理存储顺序
- 唯一索引:值唯一但允许NULL,常用于邮箱、手机号等业务唯一性校验
- 普通索引:无唯一性要求,最基础的加速手段,可建多个
- 联合索引:多列组合创建,生效需满足最左前缀原则(如索引(a,b,c),可命中a=1、a=1 AND b=2,但不命中b=2)
- 全文索引:专为文本关键词搜索设计,支持自然语言模式匹配,中文需配置ngram或升级到8.0+并启用相关插件
索引不是万能的,有明确代价
建索引会带来三方面开销:
- 磁盘空间占用:索引本身要存数据,大表的索引可能达GB级
- 写性能下降:每次INSERT/UPDATE/DELETE都要同步更新索引,尤其高并发写场景更明显
- 优化器误选风险:索引太多可能导致优化器选错执行计划,反而拖慢查询
所以索引的价值,本质是在读多写少、数据量大的场景下,用可控的写代价,换取显著的读效率提升。










