MySQL索引优化:从B+树到实战调优

张工

· 阅读 685

分享
MySQL索引优化

MySQL索引优化:从B+树到实战调优

索引是数据库性能优化的核心。一个设计良好的索引可以让查询速度提升几个数量级,而错误的索引设计不仅浪费存储空间,还可能导致查询变慢。本文从B+树的底层原理出发,讲解索引优化的实战技巧。

B+树结构理解

MySQL InnoDB使用B+树作为索引结构。B+树的特点:非叶子节点只存储键值用于导航,叶子节点存储实际数据并且通过双向链表连接。这种结构非常适合范围查询和排序操作。

理解B+树的关键:索引查找的时间复杂度是O(log N)。对于1000万行数据,B+树高度通常为3-4层,意味着每次查询只需要3-4次磁盘IO。但如果查询不走索引(全表扫描),则需要读取所有数据页。

索引设计原则

最左前缀原则:联合索引 (a, b, c) 可以支持 aa, ba, b, c 的查询,但不支持 bc 开头的查询。所以联合索引的字段顺序很重要——区分度高的字段放前面。

覆盖索引:如果查询的所有字段都在索引中,MySQL可以直接从索引返回数据,无需回表。例如索引 (user_id, name, email),查询 SELECT name, email WHERE user_id = 1 就是覆盖索引。

避免索引失效:对索引列使用函数(WHERE YEAR(create_time) = 2024)、隐式类型转换(字符串列用数字查询)、LIKE以通配符开头(LIKE '%keyword')都会导致索引失效。

实战调优

使用 EXPLAIN 分析查询执行计划。重点关注:type(ref/range比ALL好)、key(实际使用的索引)、rows(扫描行数)、Extra(Using index表示覆盖索引,Using filesort表示需要额外排序)。

使用 SHOW INDEX FROM table 查看现有索引。使用 sys.schema_unused_indexes 找出从未使用的索引,及时删除减少写入开销。使用 sys.schema_redundant_indexes 找出冗余索引(如已有(a,b)又建了(a))。

索引维护

索引不是越多越好。每个索引都会增加写入开销(INSERT/UPDATE/DELETE都需要更新索引)。一般建议单表索引不超过5-6个。定期分析索引使用情况,删除无用索引。对于大表的索引重建,可以使用 ALTER TABLE ... ALGORITHM=INPLACE 减少锁表时间。