SQL优化练习,模仿大数据量下如何优化SQL语句。通过案例介绍索引失效的场景

没有大数据量的请看这篇https://blog.csdn.net/weixin_44012722/article/details/107974662因为在大数据下的SQL才可以更好的看到优化效果
如果没有看过我这篇博客,可以先看一下这篇对SQL中EXPLAIN关键字数据的分析https://blog.csdn.net/weixin_44012722/article/details/107976412
下面我将通过案例一一介绍索引失效的场景
案例原因
给定范围的索引查询range会让后面的索引失效
复合索引最左边的列索引要作为查询索引条件,否则整个复合索引失效,当最左边的列索引作为查询索引条件时,从左到右只要中间哪个列索引不作为查询索引条件时,后面的索引就失效
案例二 中的(6)也有说明 排序 和 查找 两个要分清楚
在索引列上做任何操作(计算,函数,类型转换),会导致索引失效
到查询字段不要写*号,写字段名,*号会使索引失效
索引列作为查找条件,使用不等于(!=或<>)的时候会使索引失效
索引列作为查找条件,使用 is null , is not null 的时候会使索引失效
索引列作为查找条件,使用 like以通配符开头 % 的时候会使索引失效
这里旧的说法 or会让索引失效, 我的MYSQL版本5.5.57,or并不会让索引失效,具体哪个版本会出现这个问题,欢迎指出

案例一

1.查询员工首姓为Mary且租用日期大于 1987-02-07 的所有员工并按照生日降序排序取第一个员工数据
# 查询员工首姓为Mary且租用日期大于 1987-02-07 的所有员工并按照生日降序排序取第一个员工数据
explain select * from employees where first_name = 'Mary' and hire_date > date('1987-02-07') order by birth_date desc limit 1

在这里插入图片描述

2.创建复合索引
#创建复合索引
create index idx_employess_fhb on employees(first_name,hire_date,birth_date)
3.查看索引
#查看索引
show index from employees

在这里插入图片描述

4.explain查看查询语句,并分析

在这里插入图片描述

增加了复合索引,可以看到查询类型从all全表扫描变为了range,但是我们已经创建了birth_date字段的复合索引 idx_emplyess_fhb,可是using filesort还是存在, 这 是 因 为 给 定 范 围 的 索 引 查 询 r a n g e 会 让 后 面 的 索 引 失 效 \color{#FF0000}{这是因为给定范围的索引查询range会让后面的索引失效} range,因为一条SQL只有一个索引作为查询或排序条件,所以这里后面索引 指的就是 复合索引从左到右顺序
5.删掉索引,重新建立
#删掉索引
drop index  idx_employess_fhb on employees

#创建新的索引
create index idx_employess_fb on employees(first_name,birth_date)
6.再EXPLAIN查看查询语句,并分析

在这里插入图片描述

可以看到查询类型不但从range变为ref,Using filesort也不见了

案例二

查看员工表员工的信息 根据特定的条件
1.建立 first_name,hire_date,birth_date 三个字段的复合索引
#上面的案例一有旧的索引记得删掉,再创建这个新的
create index idx_employess_fhb on employees(first_name,hire_date,birth_date)

(1)

explain select * from employees where first_name = 'Koblick'

在这里插入图片描述

(2)

explain select * from employees where first_name = 'Koblick' and hire_date = date('19780-07-22')

在这里插入图片描述

(3)

explain select * from employees where first_name = 'Koblick' and birth_date = date('19780-07-22')

在这里插入图片描述

(4)

explain select * from employees where first_name = 'Koblick' and birth_date = date('19780-07-22') and hire_date = date('19780-07-22')

在这里插入图片描述

(5)

explain select * from employees where birth_date = date('19780-07-22')
explain select * from employees where hire_date = date('19780-07-22') and birth_date = date('19780-07-22')

在这里插入图片描述

(6)

explain select * from employees where first_name = 'Koblick' and birth_date = date('19780-07-22') order by hire_date

在这里插入图片描述

(1)-(4)与(5)作对比,我们可以得出结论,复合索引从左到右就好像火车一样,火车头必须要有(就是最左边的列要做为查询索引条件),没有最左边的列索引,整个索引失效
(2) 与 (3)、(1)做对比,我们可以得出结论,当火车头在情况下,如果中间的列索引不作为查询条件,后面的列索引将失效,因为你看 key_len (2)比(3)多3,就是因为(3)中间列索引不作为查询条件,后面的列索引将失效
(6)从中可以得出,查询和排序是两个不同功能,因为我们知道索引是用于查找和排序的,所以因为中间 hire_date作为排序条件,而作为查询条件的first_name ,birth_date,因为复合索引从左到右(first_name ,hire_date,birth_date),而查询和排序是两个不同功能,因为中间hire_date作为排序不是查找,所以后面索引失效,只用到first_name作为索引查找
总结上面两句结论,复合索引最左边的列索引要作为查询索引条件,否则整个复合索引失效,当最左边的列索引作为查询索引条件时,从左到右只要中间哪个列索引不作为查询索引条件时,后面的索引就失效,还有排序和查找两个要分清楚

案例三

explain select * from employees where left(first_name,7) = 'Koblick'
explain select * from employees where first_name = 'Koblick' and DATE_FORMAT(hire_date,'YYYY-MM-dd') = '19780-07-22'
explain select * from employees where first_name=2000

(1)用了left函数 索引失效
在这里插入图片描述(2)用了DATE_FORMAT函数 hire_date索引失效,所以key_len少了3长度
在这里插入图片描述
(3)因为 first_name 是 varchar 类型,2000是int类型,他会自动进行一个类型转换 (这里留个问号: 当我 varchar 转 int 类型就不会使索引失效,有早知道的兄弟可以评论告知一下)

在这里插入图片描述

案例四

查看员工表 first_name 为Mary
explain select * from employees where first_name = 'Mary'

在这里插入图片描述

explain select emp_no,first_name from employees where first_name = 'Mary'

在这里插入图片描述

可以看到查询字段不要写号,写字段名,表示索引被作为读取字段进行查找,效率高于号,因为*号尽管包含了索引字段名,但还是失效了

案例五

explain select * from employees where first_name != 'Mary' 
explain select * from employees where first_name <> 'Mary' 

在这里插入图片描述

可以看到在索引列作为查找条件,使用不等于(!=或<>)的时候会使索引失效

案例六

explain select * from employees where first_name is null
explain select * from employees where first_name is not null

在这里插入图片描述在这里插入图片描述

可以看到在索引列作为查找条件,使用 is null , is not null 的时候会使索引失效

案例七

explain select * from employees where first_name like '%Mary' 

在这里插入图片描述

explain select * from employees where first_name like '%Mary'
explain select * from employees where first_name like 'Mary'

在这里插入图片描述

可以看到在索引列作为查找条件,使用 like以通配符开头 % 的时候会使索引失效
当然你必须要用到like以通配符开头 % 的情况,你可以使用覆盖索引(查询字段包含索引列),如下
explain select emp_no,first_name from employees where first_name like '%Mary'
explain select emp_no,birth_date from employees where first_name like '%Mary'

在这里插入图片描述

注意:
这里提及一下 覆盖索引 ,覆盖索引就是 查询字段 只包含 索引列,SQL就会用到索引去查找数据,包含索引列以外的数据就会覆盖索引失效,接着上面的案例举个例子
explain select emp_no,last_name from employees where first_name like '%Mary'
因为last_name不是索引,索引覆盖索引失效

在这里插入图片描述






一键查询淘宝/拼多多内部优惠券,每日大额外卖红包,购物省钱的宝藏工具
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值