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都要同步更新索引,尤其高并发写场景更明显 优化器误选风险:索引太多可能导致优化器选错执行计划,反而拖慢查询所以索引的价值,本质是在读多写少、数据量大的场景下,用可控的写代价,换取显著的读效率提升。
