MySQL高级知识(七)——索引面试题分析
前言:该篇随笔通过一些案例,对索引相关的面试题进行分析。
0.准备
#1.创建test表(测试表)。
drop table if exists test;
create table test(
id int primary key auto_increment,
c1 varchar(10),
c2 varchar(10),
c3 varchar(10),
c4 varchar(10),
c5 varchar(10)
) ENGINE=INNODB default CHARSET=utf8; insert into test(c1,c2,c3,c4,c5) values('a1','a2','a3','a4','a5');
insert into test(c1,c2,c3,c4,c5) values('b1','b2','b3','b4','b5');
insert into test(c1,c2,c3,c4,c5) values('c1','c2','c3','c4','c5');
insert into test(c1,c2,c3,c4,c5) values('d1','d2','d3','d4','d5');
insert into test(c1,c2,c3,c4,c5) values('e1','e2','e3','e4','e5');
#2.创建索引。

1.根据以下Case分析索引的使用情况
Case 1:

分析:
①创建复合索引的顺序为c1,c2,c3,c4。
②上述四组explain执行的结果都一样:type=ref,key_len=132,ref=const,const,const,const。
结论:在执行常量等值查询时,改变索引列的顺序并不会更改explain的执行结果,因为mysql底层优化器会进行优化,但是推荐按照索引顺序列编写sql语句。
Case 2:


分析:
当出现范围的时候,type=range,key_len=99,比不用范围key_len=66增加了,说明使用上了索引,但对比Case1中执行结果,说明c4上索引失效。
结论:范围右边索引列失效,但是范围当前位置(c3)的索引是有效的,从key_len=99可证明。
Case 2.1:

分析:
与上面explain执行结果对比,key_len=132说明索引用到了4个,因为对此sql语句mysql底层优化器会进行优化:范围右边索引列失效(c4右边已经没有索引列了),注意索引的顺序(c1,c2,c3,c4),所以c4右边不会出现失效的索引列,因此4个索引全部用上。
结论:范围右边索引列失效,是有顺序的:c1,c2,c3,c4,如果c3有范围,则c4失效;如果c4有范围,则没有失效的索引列,从而会使用全部索引。
Case 2.2:

分析:
如果在c1处使用范围,则type=ALL,key=Null,索引失效,全表扫描,这里违背了最佳左前缀法则,带头大哥已死,因为c1主要用于范围,而不是查询。
解决方式使用覆盖索引。
结论:在最佳左前缀法则中,如果最左前列(带头大哥)的索引失效,则后面的索引都失效。
Case 3:

分析:
利用最佳左前缀法则:中间兄弟不能断,因此用到了c1和c2索引(查找),从key_len=66,ref=const,const,c3索引列用在排序过程中。
Case 3.1:

分析:
从explain的执行结果来看:key_len=66,ref=const,const,从而查找只用到c1和c2索引,c3索引用于排序。
Case 3.2:

分析:
从explain的执行结果来看:key_len=66,ref=const,const,查询使用了c1和c2索引,由于用了c4进行排序,跳过了c3,出现了Using filesort。
Case 4:

分析:
查找只用到索引c1,c2和c3用于排序,无Using filesort。
Case 4.1:

分析:
和Case 4中explain的执行结果一样,但是出现了Using filesort,因为索引的创建顺序为c1,c2,c3,c4,但是排序的时候c2和c3颠倒位置了。
Case 4.2:


分析:
在查询时增加了c5,但是explain的执行结果一样,因为c5并未创建索引。
Case 4.3:

分析:
与Case 4.1对比,在Extra中并未出现Using filesort,因为c2为常量,在排序中被优化,所以索引未颠倒,不会出现Using filesort。
Case 5:

分析:
只用到c1上的索引,因为c4中间间断了,根据最佳左前缀法则,所以key_len=33,ref=const,表示只用到一个索引。
Case 5.1:

分析:
对比Case 5,在group by时交换了c2和c3的位置,结果出现Using temporary和Using filesort,极度恶劣。原因:c3和c2与索引创建顺序相反。
总结:
通过以上Case的分析,进行如下总结:
①最佳左前缀法则。
#1.在等值查询时,更改索引列顺序,并不会影响explain的执行结果,因为mysql底层会进行优化。
#2.在使用order by时,注意索引顺序、常量,以及可能会导致Using filesort的情况。
②group by容易产生Using temporary。
③通俗理解口诀:
全值匹配我最爱,最左前缀要遵守;
带头大哥不能死,中间兄弟不能断;
索引列上少计算,范围之后全失效;
LIKE百分写最右,覆盖索引不写星;
不等空值还有or,索引失效要少用。
by Shawn Chen,2018.6.25日,下午。
相关内容
MySQL高级知识(七)——索引面试题分析的更多相关文章
- MySQL高级知识(五)——索引分析
前言:前面已经学习了explain(执行计划)的相关知识,这里利用explain对索引进行优化分析. 0.准备 首先创建三张表:tb_emp(职工表).tb_dept(部门表)和tb_desc(描述表 ...
- MySQL高级知识(六)——索引优化
前言:索引优化的目的主要是让索引不失效,本篇通过相关案例对索引优化进行讲解. 0.准备 创建经典的tb_emp表. DROP TABLE IF EXISTS `tb_emp`; CREATE TABL ...
- MySQL高级知识(三)——索引
前言:索引在sql调优部分占据着重要的位置,了解并深入索引对我们来说也是非常重要的.本篇主要介绍MySQL中索引的相关知识点. 1.索引是什么 MySQL官方对索引的定义:索引(Index)是帮助My ...
- MySQL高级知识系列目录
MySQL高级知识(一)——基础 MySQL高级知识(二)——Join查询 MySQL高级知识(三)——索引 MySQL高级知识(四)——Explain MySQL高级知识(五)——索引分析 MySQ ...
- MySQL高级知识(十四)——行锁
前言:前面学习了表锁的相关知识,本篇主要介绍行锁的相关知识.行锁偏向InnoDB存储引擎,开销大,加锁慢,会出现死锁,锁定粒度小,发生锁冲突的概率低,但并发度高. 0.准备 #1.创建相关测试表tb_ ...
- MySQL高级知识(八)——ORDER BY优化
前言:在使用order by时,经常出现Using filesort,因此对于此类sql语句需尽力优化,使其尽量使用Using index. 0.准备 #1.创建test表. drop table i ...
- MySQL高级知识(四)——Explain
前言:explain(执行计划),使用explain关键字可以模拟优化器执行sql查询语句,从而知道MySQL是如何处理sql语句.explain主要用于分析查询语句或表结构的性能瓶颈. 注:本系列随 ...
- MySQL高级知识(十三)——表锁
前言:锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算机资源(如CPU.RAM.I/O等)的争用外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是 ...
- MySQL高级知识(十一)——Show Profile
前言:Show Profile是mysql提供的可以用来分析当前会话中sql语句执行的资源消耗情况的工具,可用于sql调优的测量.默认情况下处于关闭状态,并保存最近15次的运行结果. 1.分析步骤 # ...
随机推荐
- 从零开始学安全(三十)●使用sqlmap对网站一步步渗透
常规注入步骤第一步注入点-u "url" 判断是否是注入点 有就判断用户的权限第二步获取数据库 所有的 -u "url" --dbs第三步 查看应用程序所有数据 ...
- 从零开始学安全(三)●黑客常用的windows端口
端口可选1-65536 1-1024 预保留端口 留给windows系统服务的 下面是常见的端口对应的服务 1 TCP Port Service Multiplexer 传输控制协议端口服务多路开关选 ...
- CSharp工程中的几个文件
以下基于.NET Framework4.6及.NET Core2.0 .csproj 用于配置项目信息,如: 程序集名称.类型 Framework版本 项目所包含的文件信息,如:cs.html.js. ...
- Java爬虫框架Jsoup学习记录
Jsoup的作用 当你想获得某网页的内容,可以使用此框架做个爬虫程序,爬某图片网站的图片(先获得图片地址,之后再借助其他工具下载图片)或者是小说网站的小说内容 我使用Jsoup写出的一款小说下载器,小 ...
- 【Java每日一题】20170207
20170206问题解析请点击今日问题下方的“[Java每日一题]20170207”查看(问题解析在公众号首发,公众号ID:weknow619) package Feb2017; public cla ...
- 解决mysql服务无法启动的问题
今天,mysql突然无法启动了. 解决办法记录一下: 1.删除data文件 我的:C:\Program Files\MySQL\MySQL Server 5.7\data 注意:这个文件可能在你一直试 ...
- Java中的深克隆和浅克隆
为什么要克隆 首先思考一个问题, 为什么需要克隆对象? 直接new一个对象不行吗? 克隆的对象可能包含一些已经修改过的属性, 而new出来的对象的属性都还是初始化时候的值, 所以当需要一个新的对象来保 ...
- linux防火墙相关 iptables
1. root用户查看防火墙状态(非root用户无权限查看) 查看防火墙状态: service iptables status 2.开启和关闭防火墙 //开启防火墙: service iptables ...
- JavaScript面试技巧之数组的一些不low操作
本文主要从应用来讲数组api的一些骚操作; 如一行代码扁平化n维数组.数组去重.求数组最大值.数组求和.js排序.对象和数组的转化等: 上面这些应用场景你可以用一行代码实现? 1.扁平化n维数组 1. ...
- js替换字符中的斜杠反斜杠
var reg=/\\|\//g; var a="a\a\\a/b" alert(a.replace(reg,"-"));