使用覆盖索引解决 LIKE以%开头会导致索引失效问题

1 建立索引

CREATE INDEX idx_nameAgePos ON staff(name, age, pos);
1.1 测试&Explain分析

IndexCase#1:查询Id

EXPLAIN SELECT id FROM staff WHERE name LIKE ‘%Alice%’;
在这里插入图片描述

结果:使用上了索引(因为 name 有索引,同时查询的 Id 是主键肯定也有索引)

IndexCase#2:查询name

EXPLAIN SELECT name FROM staff WHERE name LIKE ‘%Alice%’;

在这里插入图片描述

结果:使用上了索引(因为查询条件和查询字段都是有索引的 name)

IndexCase#3:查询age

EXPLAIN SELECT age FROM staff WHERE name LIKE ‘%Alice%’;

在这里插入图片描述

结果:使用上了索引(因为查询条件的 name 以及查询字段的 age 都有索引)

IndexCase#4:查询 id & name

EXPLAIN SELECT id, name FROM staff WHERE name LIKE ‘%Alice%’;
在这里插入图片描述

结果:使用上了索引(因为查询条件的 name 以及查询字段的 id & name 都有索引)

IndexCase#5:查询 name & age

EXPLAIN SELECT name, age FROM staff WHERE name LIKE ‘%Alice%’;
在这里插入图片描述

结果:使用上了索引(因为查询条件的 name 以及查询字段的 name & age 都有索引)

IndexCase#6:查询 id & name & age

EXPLAIN SELECT id, name, age FROM staff WHERE name LIKE ‘%Alice%’;
在这里插入图片描述

结果:使用上了索引(因为查询条件的 name 以及查询字段的 id & name & age 都有索引)

IndexCase#7:查询 id & name & age & salary (提示:salary 不在索引列中)

EXPLAIN SELECT id, name, age, salary FROM staff WHERE name LIKE ‘%Alice%’;
在这里插入图片描述

结果:没有索引,type=all,全表扫描!(因为查询字段中多了个 salary 而 salary 不在索引列中)

IndexCase#8:查询 *

EXPLAIN SELECT * FROM staff WHERE name LIKE ‘%Alice%’;
在这里插入图片描述

结果:没有索引,type=all,全表扫描!(因为 * 包含 salary 而 salary 不在索引列中)

通过 IndexCase#4 到 IndexCase#11 可以看出,当真的需要两边都使用%来模糊查询时,只有当这个作为模糊查询的条件字段(例子中的name)以及所想要查询出来的数据字段(例子中的 id & name & age)都在索引列上时,才能真正使用索引,否则,索引失效全表扫描(比如多了一个 salary 字段)。我想,这应该就是 ‘覆盖索引(索引覆盖)’ 的本质吧。同时,这也能很好的证实 “尽量避免SELECT * 而是一一罗列出所需要查询的字段” 的道理吧,因为,搞不好 SELECT * 就多了一个字段,就导致了全表扫描。

2 结论

LIKE以%开头会导致索引失效;使用覆盖索引解决之

你可能感兴趣的:(数据库,mysql)