索引将全表扫描的O(n)查询降为O(log n),通过B+树减少磁盘IO、支持有序范围查询、避免回表;显著加速WHERE、JOIN、GROUP BY、ORDER BY及聚合操作,但过多索引会降低写性能、增加空间与维护成本。

因为索引把“大海捞针”变成了“按图索骥”。没有索引时,MySQL每次查询都要从第一行扫到最后一行(全表扫描),数据量越大,耗时越长;有了索引,数据库能直接跳转到目标数据的位置,查询复杂度从 O(n) 降到 O(log n),响应常常压缩在毫秒级。
索引让查询变快的核心机制
MySQL 主流使用 B+ 树索引结构,它的设计天然适配磁盘 I/O 和快速定位:
- 减少磁盘读取次数:B+ 树高度低、扇出大,几层就能覆盖千万级数据;一次查询通常只需 2–4 次磁盘 IO,远少于全表扫描动辄成百上千次。
-
有序存储加速范围查询:索引列值在叶子节点中物理有序排列,
WHERE age BETWEEN 25 AND 30或ORDER BY created_at可以连续读取,无需额外排序。 -
避免回表(如果用的是覆盖索引):当
SELECT的字段全部包含在索引中,MySQL 直接从索引里取值,不用再回主键索引查整行数据。
哪些操作直接受益于索引
不只是 WHERE 条件匹配,这些常见场景也依赖索引提速:
-
JOIN 连接:关联字段(如
user_id)建索引后,MySQL 能快速匹配两表对应行,避免嵌套循环全扫。 - GROUP BY / ORDER BY:如果分组或排序字段上有索引,MySQL 可直接利用索引的有序性,省去临时表和文件排序步骤。
-
聚合函数加速:例如
COUNT(*)在 InnoDB 中可走主键索引统计行数(不加 WHERE 时),比遍历更快。 - 唯一性校验与约束:主键、UNIQUE 索引在插入/更新时自动检查重复,底层靠索引的快速查找实现。
不建索引或乱建索引的代价
索引不是越多越好,它是一把双刃剑:
- 写性能下降:每插入/更新/删除一行,所有相关索引都要同步修改,频繁写的表容易成为瓶颈。
- 占用额外空间:一个索引≈一张精简版表;多个大字段组合索引,可能比原表还占空间。
- 优化器选错索引:索引太多时,MySQL 可能误判成本,放弃最优路径,反而用上低效索引甚至全表扫描。
-
维护开销增加:大量数据变更后,索引可能碎片化,需定期
OPTIMIZE TABLE或重建。
什么时候该建索引
优先考虑以下列建索引,效果最明显:
-
WHERE 条件中高频出现的列,尤其是等值查询(
=)、范围查询(>,BETWEEN)。 -
经常用于 JOIN 的外键列,比如订单表的
user_id、商品表的category_id。 - ORDER BY 或 GROUP BY 的字段,特别是多字段组合顺序与索引顺序一致时。
-
SELECT 列较少且固定,可设计覆盖索引,例如
INDEX (status, create_time, id)支撑SELECT id FROM t WHERE status=1 ORDER BY create_time。










