索引什么是索引索引是数据库中对表中一列或多列的值进行排序的一种数据结构。索引的作用加快数据检索的速度通过减少查询过程中需要扫描的数据行数。加快表连接和排序索引本身是有序的数据库可以直接利用索引的有序性完成排序避免额外的文件排序Filesort操作。保证数据的唯一性通过创建唯一索引UNIQUE数据库可以强制保证某列或多列数据的唯一性。简单来说就是以存储空间换取查询时间的极大缩短。索引的代价缺点占用存储空间每个索引都需要额外的磁盘空间来存储索引结构。降低写入性能对表进行 INSERT、UPDATE、DELETE 时除了修改数据本身还需要同步维护所有相关索引写操作成本上升。可能失效或误用索引使用不当如违反最左前缀、字段类型不匹配等不仅无法加速反而可能拖慢查询。因此索引并非越多越好需要根据实际查询场景权衡。索引的原理B树B树是 B 树的一种变种。分层的节点结构B树由根节点、内部节点和叶子节点构成。内部节点只记录存储索引键值和指向子节点的指针不存储实际数据。叶子节点所有的数据都存储在叶子节点上这些叶子节点通过双向链表连接形成了一个有序的数据序列。树高稳定所有叶子节点都在同一层这意味着查找任何数据都需要经历相同层数的路径查询时间非常稳定。为什么使用 B树大幅减少磁盘 I/O磁盘 I/O 是数据库操作中最慢的环节。B树通过其矮胖的结构将查找数据所需的磁盘读取次数降到最低通常 2-3 次。每个节点的大小通常被设计为等于一个磁盘页如 MySQL 的 16KB使得一次 I/O 就能读取一个完整的节点。相比之下二叉树等结构在数据量大时树高会急剧增加导致 I/O 次数剧增。卓越的范围查询能力数据库的范围查询如 BETWEEN、、非常频繁。B树的叶子节点通过链表串联一旦定位到范围的起点只需沿着链表顺序扫描即可效率极高。而 B 树的数据分散在各处进行范围查询需要进行复杂的中序遍历效率低下。查询性能稳定在 B树中任何查找都必须从根节点走到叶子节点因此所有查询的路径长度都相同查询效率非常稳定。而在 B 树中数据可能存储在任意节点数据靠近根节点时查询快靠近叶子节点时查询慢性能不稳定。更高的空间利用率由于内部节点不存数据可以存储更多的键值这进一步降低了树的高度也使得数据在磁盘上存储得更紧密具有良好的空间局部性能提高缓存命中率。索引的分类按物理存储方式以 MySQL InnoDB 为例聚集索引Clustered Index索引的叶子节点直接存储整行数据数据即索引主键索引就是聚集索引。每张表只能有一个。非聚集索引二级索引 / Secondary Index叶子节点存储的是主键值而非数据本身需要通过主键再查一次数据。可以有多个。相关概念回表通过非聚集索引查询到主键后再用主键去聚集索引中查找完整数据行的过程。覆盖索引查询所需的列全部包含在索引中时无需回表直接返回结果性能最高。按功能/约束分类主键索引Primary Key唯一且非空InnoDB 中即聚集索引。唯一索引Unique保证列值唯一允许 NULL。普通索引Normal最基本的索引无任何约束。联合索引复合索引 / Composite由多个列组合成的索引遵循最左前缀原则。全文索引Fulltext用于大文本的全文检索。前缀索引对字符串的前 N 个字符建立索引节省空间。联合索引与最左前缀原则联合索引由多列组成例如INDEX(a, b, c)内部排序规则是先按 a 排序a 相同再按 b 排序b 相同再按 c 排序。最左前缀原则查询条件必须从联合索引的最左侧列开始且不能跳过中间列否则无法完全利用该索引。例如对INDEX(a, b, c)能走索引where a ?、where a ? and b ?、where a ? and b ? and c ?不能走索引where b ?、where c ?、where a ? and c ?跳过 b只能用到 a 这一列索引失效的常见场景对索引列使用函数或表达式运算如where year(create_time) 2025隐式类型转换如字符串列与数字比较where phone 13800000000使用like以%开头如where name like %张三联合索引违反最左前缀原则查询条件使用OR且存在非索引列使用!、、not in等可能不走索引索引列参与计算如where age 1 20建立索引的建议为 WHERE、ORDER BY、GROUP BY、JOIN 中频繁使用的列建索引。区分度高选择性好的列适合建索引如主键、唯一字段。联合索引要注意列的顺序把区分度高、查询频繁的列放在最左。避免在频繁更新的列上建过多索引。尽量使用覆盖索引减少回表。