覆盖索引:减少回表查询
一、什么是覆盖索引 1.1 回表查询 -- 表结构 CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(50), age INT, email VARCHAR(100) ); CREATE INDEX idx_name ON users(name); -- 查询 SELECT * FROM users WHERE name = '张三'; 查询过程: 在idx_name索引找到name=‘张三’,获取id=10 回表:到主键索引查找id=10的完整数据 返回结果 IO次数:2次(索引1次 + 回表1次) 1.2 覆盖索引 -- 查询 SELECT id, name FROM users WHERE name = '张三'; 查询过程: 在idx_name索引找到name=‘张三’ 索引中已包含id和name 直接返回,无需回表 IO次数:1次(只查索引) 覆盖索引:查询的列都在索引中,无需回表。 二、覆盖索引的优势 2.1 减少IO -- 无覆盖索引 SELECT * FROM users WHERE name = '张三'; -- IO:索引 + 回表 = 2次 -- 覆盖索引 SELECT id, name FROM users WHERE name = '张三'; -- IO:索引 = 1次 2.2 提升性能 -- 测试 -- 100万数据,查询10000次 -- SELECT *(需要回表) -- 耗时:5秒 -- SELECT id, name(覆盖索引) -- 耗时:0.5秒 -- 性能提升:10倍 三、如何实现覆盖索引 3.1 主键索引天然覆盖 -- 主键索引是聚簇索引,包含完整数据 SELECT * FROM users WHERE id = 10; -- 覆盖索引 3.2 设计联合索引 -- 查询 SELECT id, name, age FROM users WHERE name = '张三'; -- 索引设计 CREATE INDEX idx_name_age ON users(name, age); -- 索引包含:name, age, id(主键自动包含) -- 覆盖查询所需列 3.3 添加冗余列 -- 查询 SELECT user_id, order_no, status FROM orders WHERE user_id = 123; -- 索引设计 CREATE INDEX idx_user_no_status ON orders(user_id, order_no, status); -- order_no和status可能不在WHERE中,但在SELECT中 -- 添加到索引实现覆盖 四、EXPLAIN中的覆盖索引 4.1 Using index EXPLAIN SELECT id, name FROM users WHERE name = '张三'; 结果: ...