持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
索引失效的 十大原因
1. 全值匹配
测试:
EXPLAIN select * from sys_order
输出结果:
可以看到进行了全表扫描
测试:
EXPLAIN select order_payment_type from sys_order
输出结果:
在生产中尽量少使用select * 去查询。给查询频率高的字段创建索引
2. 最佳左前缀法
测试:
//创建复合索引
ALTER TABLE sys_order ADD INDEX index_name(order_create_id,order_payment_type);
EXPLAIN select * from sys_order where order_create_id="C25097"
输出结果:
按照索引的顺序进行使用,最佳左前缀法即是第一个不能边 而且中间列不能断
3. 不在所引列上做任何操作(计算 函数 or 类型转换)会导致索引失效而转向全表扫描
测试:
EXPLAIN select * from sys_order where order_create_id="C25097" or order_payment_type="无"
输出结果:
可以看到 添加 or 条件后 索引失效
测试:添加函数
EXPLAIN select * from sys_order where left(order_create_id,4)="付款"
输出结果:
可以看到 索引失效
4. 存储引擎不能使用索引中范围条件右边的列
测试三个索引:
EXPLAIN select * from sys_order where order_create_id="C25097"
and order_entering_userid = 25 and order_payment_type="企业店付款"
输出结果:
这里我们可以看到 key_len的值 为777
测试添加范围>:
EXPLAIN select * from sys_order where order_create_id="C25097"
and order_entering_userid > 25 and order_payment_type="企业店付款"
输出结果:
我们发现 key_len的数值为 772
测试前两个索引:
EXPLAIN select * from sys_order where order_create_id="C25097" and order_entering_userid = 25
输出结果:
可以看到我们前两个索引的key_len的值为772 由此我们可以看到范围条件后 所引列并没有生效。
5. 计量使用覆盖索引(只访问索引的查询(所引列和查询类一致)),减少select *
测试按需索取字段:
EXPLAIN select order_create_id from sys_order where order_create_id="C25097" and order_entering_userid = 25
输出结果:
测试 查询全部:
EXPLAIN select * from sys_order where order_create_id="C25097" and order_entering_userid = 25
输出结果:
由此我们可以看到 按需索取比* 新能更加强大
6. mysql在使用不等于(!= 或者<>) 的时候无法使用索引会导致 全表扫描
测试:
EXPLAIN select * from sys_order where order_create_id!="C25097"
输出结果:
由此我们可以看到索引失效
7. is null,is not null 也无法使用索引
测试:
EXPLAIN select * from sys_order where order_create_id is not null
输出结果:
理论上有使用但是实际上key为空 所以索引失效
8. like以通配符开头(’%abc‘)mysql 索引失效变成全表扫描
测试 左右都有%:
EXPLAIN select * from sys_order where order_create_id like "%C%"
输出结果:
可以看到索引失效
测试 只有左边有%:
EXPLAIN select * from sys_order where order_create_id like "%C"
输出结果:
可以看到索引失效
测试 只有右边有%:
EXPLAIN select * from sys_order where order_create_id like "C%"
输出结果:
可以看到索引生效了,但是实际开发中 左右都有% 更为常见
测试 使用复合索引:
EXPLAIN select order_create_id,order_entering_userid,order_payment_type
from sys_order where order_create_id like "%C%"
输出结果:
可以看到 索引并没有失效。注意复合索引不能有复合索引列外的列。
9. 字符串不加单引号索引失效
测试 varchar类型不加引号:
EXPLAIN select * from sys_order where order_create_id = 25097
输出结果:
可以看到 索引失效实际并没有使用索引
测试 varchar类型加引号:
EXPLAIN select * from sys_order where order_create_id = "25097"
输出结果:
可以看到索引生效了
10. 少用 or,用它来连接时会导致索引失效
测试:
EXPLAIN select * from sys_order
where order_create_id = "25097" or order_entering_userid = 25087
输出结果:
可以看到索引失效了
实践是检验真理的唯一方法! 明天见🥰🥰🥰