看这篇就够了!MySQL 索引知识点超全总结( 四 )
select * from employees where hire_date > '1990-01-14' and first_name like 'Hi%';
- 在 MySQL 5.5 执行 explain,extra 字段的值显示没有使用索引

文章插图
执行查询花费时间为 0.12s

文章插图
- 在 MySQL 5.7 执行 explain,extra 字段的值显示使用了索引下推

文章插图
执行查询花费时间为 0.02s

文章插图
- 索引下推
MRR 优化MySQL 5.6 版本开始支持 Multi-Range Read(MRR)优化,MRR 优化的目的是为减少磁盘的随机访问,并且将随机访问转化为较为顺序的数据访问,对于 IO-bound 类型的 SQL 查询语句可带来性能极大提升 。我们先看下对比测试,以下测试语句在同一个 MySQL 实例下执行,执行前均进行 mysql 服务重启,以保证缓存此没被预热 。
- 关闭 MRR
SET @@optimizer_switch='mrr=off';select * from employees where hire_date > '1990-01-14' and first_name like 'Hi%';
执行耗时为 0.90s
文章插图
- 开启 MRR
SET @@optimizer_switch='mrr=on,mrr_cost_based=off'; select * from employees where hire_date > '1990-01-14' and first_name like 'Hi%';

文章插图
- 分析
常见的索引失效场景在 MySQL 表中建立了索引,SQL 查询语句就会一定使用到索引么?不一定,存在着索引失效的场景 。我们给 employees 表增一个组合索引,后续例子均基于此表进行分析、测试 。
alter table employees add index i_b_f_l(birth_date, first_name, last_name)alter table employees add index i_h(hire_date);

文章插图
失效场景
- 范围查询(>,<,<>)
explain select * from employees where hire_date > '1989-06-02';

文章插图
- 查询条件类型不一致
alter table employees add index i_first_name (first_name);explain select * from employees where first_name = 1;

文章插图
- 查询条件使用了函数
explain select * from employees where CHAR_LENGTH(hire_date) = 10;

文章插图
- 模糊查询
explain select * from employees where hire_datelike'%1995';

文章插图
- 不使用组合索引的首个字段当条件
explain select * from employees where last_name = 'Kalloufi' and first_name = 'Saniya';

文章插图
为什么会失效?
- 顺序读比离散读性能要好
范围查询一定会导致索引失效么?并不会!稍微更改下查询条件看下 explain 的对比结果,可以看到新语句用到索引下推,说明索引并未失效 。为什么?在不使用覆盖索引的情况下,优化器只有在数据量小的时候才会选择使用非聚集索引 。受制于传统的机械磁盘特性,通过聚集索引顺序读数据行的性能会比通过非聚集索引离散读数据行要好 。所以,优化器在即使有非聚集索引、但是访问数据量可能达到送记录数的 20%时会选择聚集索引 。当然也可以用 Force index 强制使用索引 。
推荐阅读
- 像素150dpi是什么意思?图片150dpi是什么意思_4
- 只需一条命令,就可以查出哪些端口被防火墙阻止了,真方便
- 不推荐别的了,IDEA 自带的数据库工具就很牛逼
- 一次解决mysql锁表问题的经历
- 音频如何剪切?电脑上处理音频用这个方法就够了
- 怎么查看电脑配置?这4种方法一定要学会
- 从 Linux 源码看 Socket 的阻塞和非阻塞
- 吃鸡蛋的禁忌有哪些?
- 陕西|47场特色服务活动!找工作的你看过来
- 艾尔登法环|光有了好看的衣服可不行,包包也得跟上