【原创】面试官:谈谈你对mysql联合索引的认识?
引言
本文预计分为两个部分:
(1)联合索引部分的基础知识
在这个部分,我们温习一下联合索引的基础
(2)联合索引部分的实战题
在这个部分,列举几个我认为算是实战中的代表题,挑出来说说。
正文
基础
讲联合索引,一定要扯最左匹配!放心,我不扯有的没的,几句话懂个大概就行!
最左匹配
所谓最左原则指的就是如果你的 SQL 语句中用到了联合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个联合索引去进行匹配,值得注意的是,当遇到范围查询(>、<、between、like)就会停止匹配。
假设,我们对(a,b)字段建立一个索引,也就是说,你where后条件为
a = 1
a = 1 and b = 2
是可以匹配索引的。但是要注意的是~你执行
b= 2 and a =1
也是能匹配到索引的,因为Mysql有优化器会自动调整a,b的顺序与索引顺序一致。
相反的,你执行
b = 2
就匹配不到索引了。
而你对(a,b,c,d)建立索引,where后条件为
a = 1 and b = 2 and c > 3 and d = 4
那么,a,b,c三个字段能用到索引,而d就匹配不到。因为遇到了范围查询!
最左匹配的原理?
假设,我们对(a,b)字段建立索引,那么入下图所示

如图所示他们是按照a来进行排序,在a相等的情况下,才按b来排序。
因此,我们可以看到a是有序的1,1,2,2,3,3。而b是一种全局无序,局部相对有序状态!
什么意思呢?
从全局来看,b的值为1,2,1,4,1,2,是无序的,因此直接执行b = 2这种查询条件没有办法利用索引。
从局部来看,当a的值确定的时候,b是有序的。例如a = 1时,b值为1,2是有序的状态。当a=2时候,b的值为1,4也是有序状态。
因此,你执行a = 1 and b = 2是a,b字段能用到索引的。而你执行a > 1 and b = 2时,a字段能用到索引,b字段用不到索引。因为a的值此时是一个范围,不是固定的,在这个范围内b值不是有序的,因此b字段用不上索引。
综上所示,最左匹配原则,在遇到范围查询的时候,就会停止匹配。
实战
OK,懂上面的基础,我们就可以开始扯了~我举了经典的五大题型,看完基本就懂!
题型一
如果sql为
SELECT * FROM table WHERE a = 1 and b = 2 and c = 3;
如何建立索引?
如果此题回答为对(a,b,c)建立索引,那都可以回去等通知了。
此题正确答法是,(a,b,c)或者(c,b,a)或者(b,a,c)都可以,重点要的是将区分度高的字段放在前面,区分度低的字段放后面。像性别、状态这种字段区分度就很低,我们一般放后面。
例如假设区分度由大到小为b,a,c。那么我们就对(b,a,c)建立索引。在执行sql的时候,优化器会 帮我们调整where后a,b,c的顺序,让我们用上索引。
题型二
如果sql为
SELECT * FROM table WHERE a > 1 and b = 2;
如何建立索引?
如果此题回答为对(a,b)建立索引,那都可以回去等通知了。
此题正确答法是,对(b,a)建立索引。如果你建立的是(a,b)索引,那么只有a字段能用得上索引,毕竟最左匹配原则遇到范围查询就停止匹配。
如果对(b,a)建立索引那么两个字段都能用上,优化器会帮我们调整where后a,b的顺序,让我们用上索引。
题型三
如果sql为
SELECT * FROM `table` WHERE a > 1 and b = 2 and c > 3;
如何建立索引?
此题回答也是不一定,(b,a)或者(b,c)都可以,要结合具体情况具体分析。
拓展一下
SELECT * FROM `table` WHERE a = 1 and b = 2 and c > 3;
怎么建索引?嗯,大家一定都懂了!
题型四
SELECT * FROM `table` WHERE a = 1 ORDER BY b;
如何建立索引?
这还需要想?一看就是对(a,b)建索引,当a = 1的时候,b相对有序,可以避免再次排序!
那么
SELECT * FROM `table` WHERE a > 1 ORDER BY b;
如何建立索引?
对(a)建立索引,因为a的值是一个范围,这个范围内b值是无序的,没有必要对(a,b)建立索引。
拓展一下
SELECT * FROM `table` WHERE a = 1 AND b = 2 AND c > 3 ORDER BY c;
怎么建索引?
题型五
SELECT * FROM `table` WHERE a IN (1,2,3) and b > 1;
如何建立索引?
还是对(a,b)建立索引,因为IN在这里可以视为等值引用,不会中止索引匹配,所以还是(a,b)!
拓展一下
SELECT * FROM `table` WHERE a = 1 AND b IN (1,2,3) AND c > 3 ORDER BY c;
如何建立索引?此时c排序是用不到索引的。
总结
希望大家在面试的时候遇到联合索引的题目,能够答出来吧
【原创】面试官:谈谈你对mysql联合索引的认识?的更多相关文章
- 我说MySQL联合索引遵循最左前缀匹配原则,面试官让我回去等通知
面试官: 我看你的简历上写着精通MySQL,问你个简单的问题,MySQL联合索引有什么特性? 心想,这还不简单,这不是问到我手心里了吗? 听我给你背一遍八股文! 我: MySQL联合索引遵循最左前缀匹 ...
- 面试官:"谈谈分库分表吧?"
原文链接:面试官:"谈谈分库分表吧?" 面试官:“有并发的经验没?” 应聘者:“有一点.” 面试官:“那你们为了处理并发,做了哪些优化?” 应聘者:“前后端分离啊,限流啊 ...
- 跟面试官侃半小时MySQL事务,说完原子性、一致性、持久性的实现
提到MySQL的事务,我相信对MySQL有了解的同学都能聊上几句,无论是面试求职,还是日常开发,MySQL的事务都跟我们息息相关. 而事务的ACID(即原子性Atomicity.一致性Consiste ...
- 【MySQL】面试官问我:MySQL如何实现无数据插入,有数据更新?我是这样回答的!
写在前面 马上就是金九银十的跳槽黄金期了,很多读者都开始出去面试了.这不,又一名读者出去面试被面试官问了一个MySQL的问题:向MySQL中插入数据,如何实现MySQL中没有当前id标识的数据时插入数 ...
- 三道MySQL联合索引面试题,淘汰80%的面试者,你能答对几道
众所周知MySQL联合索引遵循最左前缀匹配原则,在少数情况下也会不遵循(有兴趣,可以翻一下上篇文章). 创建联合索引的时候,建议优先把区分度高的字段放在第一列. 至于怎么统计区分度,可以按照下面这种方 ...
- MySQL联合索引运用-最左匹配原则
前言 之前看了很多关于MySQL索引的文章也看了<高性能MySQL>这本书,自以为熟悉了MySQL索引使用原理,入职面试时和面试官交流,发现对复合索引的使用有些理解偏颇,发现自己的不足整理 ...
- MySQL联合索引最左匹配范例
MySQL联合索引最左匹配范例 参考文章:http://blog.jobbole.com/24006/ 创建示例表. 示例表来自MySQL官方文档: https://dev.mysql.com/doc ...
- MySQL 联合索引详解
MySQL 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c ...
- mysql 联合索引(转)
http://blog.csdn.net/lmh12506/article/details/8879916 mysql 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中 ...
随机推荐
- PHP导出excel文件的多种方式
1.第一种实现的方法 set_time_limit(0); //逐条导出数据 ob_end_clean(); header("Content-type: application/vnd.ms ...
- 在腾讯云服务器上安装JDK+Tomcat并启动tomcat
由于Java web项目需要使用到tomcat所以决定在腾讯云服务器(centos7.X)上安装JDK和tomcat,来部署我们的项目. 准备工具: 云服务器:centos7.x+ 本地连接服务器:X ...
- c++入门资源
http://www.cnblogs.com/jackyyang7/articles/2479482.htmlvs2010编译器的使用 https://www.cnblogs.com/me115/ar ...
- 为啥java要使用 set ()和get()方法---封装
封装性:属性封装,方法封装,类封装,组件封装等 例如:如果属性没有封装,那么在本类对象之外创建对象后,可以直接访问属性 private关键字,只能在本类中访问,想要在外部访问私有属性,我们需要提供公有 ...
- 导致提前layout的常见情况(通过chrome浏览器自带的控制台可以看到)
1.通过js获取DOM属性 2.增/删/DOM节点 3.改变浏览器窗口大小 4.改变字体 5.激活css伪类 6.修改DOM的属性,涉及到大小.位置等(该颜色不会激活提前的layout) 7.其他js ...
- Rime输入法一些设定
有鉴于谷歌搜狗拼音等不太好用,但是博主一直页没找到合心的输入法,直到遇见Rime,中州韵就是我想要的输入法.记录一下自己用的时候的修改,以备查询.注意:缩进不要弄丢,所有更改完都需要重新部署才能生效. ...
- MySQL5.7彻底取消主从复制
由于手误在master节点执行了stop slave;->change master to XXX;->start slave;的动作,后面虽然使用stop slave停止了主从复制,但是 ...
- Android空包签名
空包签名 搜狗.优亿等Android市场,上传应用需要提供一个与要上传的应用相同签名的空包.这个空包是相应官方市场提供的,下载好之后需要使用命令行进行签名.具命令如下: 1 jarsigner -ve ...
- 虚拟桌面软件CitrixReceiver相关问题
由于安过一次,卸载再次安装程序报错: 原因:卸载不干净,导致再次安装部分插件未成功安装 解决: 1.在控制面板卸载Citrix receiver 2.删除C:\Program Files (x86)\ ...
- Requests功能整理
import requests # GET r = requests.get('https://api.github.com/events') # POSTr = requests.post('htt ...