-
Using where
服务器层过滤。 -
Using index
覆盖索引,不需要回表。 -
Using index condition
使用了索引下推优化(Index Condition Pushdown, ICP)。where子句中的部分条件虽然不能通过索引快速定位(如模糊查询、不符合最左前缀原则),但索引列里包含这个字段,存储引擎在扫描索引时直接过滤数据,减少回表次数。
示例
mysql版本8.0
CREATE TABLE `users` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(50),
`age` INT,
`city` VARCHAR(50),
INDEX idx_age_city (`age`, `city`) -- 复合索引:age, city
) ENGINE=InnoDB;
- Using where
EXPLAIN SELECT *
FROM users
WHERE name = 'Alice';
- Using index
EXPLAIN SELECT age, city
FROM users
WHERE age = 30;
- Using where; Using index
EXPLAIN SELECT age, city
FROM users
WHERE age = 30 and city like '%ong%';
索引包含所有选择列,不需要回表,city like '%ong%'需要在服务器层过滤。
- Using index condition
EXPLAIN SELECT *
FROM users
WHERE age = 30 and city like '%ong%';
select *需要回表,把city like '%ong%'放到索引扫描时过滤,减少回表次数。
- Using index condition; Using where
EXPLAIN SELECT *
FROM users
WHERE age = 30 and city like '%ong%' and `name` = 'Alice';
- age = 30,通过索引快速定位。
- city like '%ong%',无法通过索引快速过滤,但通过ICP,存储引擎会在扫描索引时检查该条件,减少回表次数。
- name = 'Alice',需要回表后由服务器层过滤。
对Using where的理解。
mysql的分层设计决定了只要不能通过索引精确定位的条件都应该在服务器层过滤。
ICP不是为了避免Using where,而是为了避免回表,减少回表次数。回表的代价大,而不能通过索引快速定位的过滤放到存储引擎层还是放到服务器层区别不大。