索引是 MySQL 性能优化的核心手段,合理的索引设计能让查询从秒级降到毫秒级。
B+Tree 索引原理
MySQL InnoDB 使用 B+Tree 作为索引数据结构:
- 非叶子节点只存储键值,不存储数据
- 叶子节点存储完整数据,并通过指针连接
- 查询时从根节点出发,逐层定位到叶子节点
联合索引最左前缀法则
创建联合索引时,列的顺序至关重要:
CREATE INDEX idx_name_age ON users(name, age);
以下查询可以使用索引:
SELECT * FROM users WHERE name = '张三';
SELECT * FROM users WHERE name = '张三' AND age = 20;
以下查询无法使用索引:
SELECT * FROM users WHERE age = 20; -- 缺少最左列
覆盖索引
如果查询的所有列都在索引中,可以避免回表:
CREATE INDEX idx_name_age ON users(name, age);
-- 覆盖索引,无需回表
SELECT name, age FROM users WHERE name = '张三';
-- 需要回表查询其他列
SELECT * FROM users WHERE name = '张三';
索引下推(ICP)
MySQL 5.6 引入的索引下推优化:
SELECT * FROM users WHERE name LIKE '张%' AND age = 20;
没有 ICP 时,存储引擎先根据 name 找到所有记录,再回表过滤 age。 有 ICP 时,存储引擎在索引层面就过滤掉不符合 age 条件的记录,减少回表次数。
慢查询分析
开启慢查询日志:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
使用 EXPLAIN 分析查询计划:
EXPLAIN SELECT * FROM users WHERE name = '张三';
关注 type、key、rows、Extra 字段。