三道MySQL联合索引面试题,淘汰80%的面试者,你能答对几道
众所周知MySQL联合索引遵循最左前缀匹配原则,在少数情况下也会不遵循(有兴趣,可以翻一下上篇文章)。
创建联合索引的时候,建议优先把区分度高的字段放在第一列。
至于怎么统计区分度,可以按照下面这种方式。
创建一张测试表,用来测试:
CREATE TABLE `test` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`a` int NOT NULL,
`b` int NOT NULL,
`c` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='测试表';
统计每个字段的区分度:
select
count(distinct a)/count(*),
count(distinct b)/count(*),
count(distinct c)/count(*)
from test;

值越大,区分度越高,优先放在第一列。
很多人不知道联合索引在B+树中是怎么存储的?我简单画一下。
比如在(a,b)字段上面创建联合索引,存储结构类似下面这样:

叶子节点存储全部数据,用顺序指针相连,数据都是先按a字段排序,a字段的值相等时再按b字段排序。
a字段的值是全局有序的,分别有1,1,1,2,2,2。
b字段的值是全局无序的,分别有1,3,5,1,3,5,只有在a字段的值相等时才呈现出局部有序。
所以在进行SQL查询的时候,如果where条件中没有a字段,只有b字段,是无法用到索引的,像下面这样:
select * from test where b=1;
像有些文章上面说的,在(a,b)两个字段上创建联合索引,就会创建两个索引,分别是(a)和(a,b),这其实是一种不恰当的表述,虽然结果是对的。
下面做几道联合索引的经典面试题,试一下大家掌握的怎么样?
第一题:
下面这条SQL,该怎么创建联合索引?
SELECT * FROM test WHERE a = 1 and b = 1 and c = 1;
你以为的答案是(a,b,c),其实答案是6个,abc三个的排列组合,(a,b,c)、(a,c,b)、(b,a,c)、(b,c,a)、(c,a,b)、(c,b,a)。
MySQL优化器为了适应索引,会调整条件的顺序。
再给面试官补充一句,区分度高的字段放在最前面,大大加分。
第二题:
下面这条SQL,该怎么创建联合索引?
SELECT * FROM test WHERE a = 1 and b > 1 and c = 1;
考察的知识点是: 联合索引遇到范围匹配会停止,不会再匹配后面的索引字段。
所以答案应该是:(a,c,b)和 (c,a,b)。
当创建(a,c,b)和 (c,a,b)索引的时候,查询会用到3个字段的索引,效率更高。
怎么判断是用到了3个字段的索引,而不是只用到前两个字段的索引呢?
有个非常简单的方法,看执行计划的索引长度。

由于int类型的字段占4个字节,3个字段长度刚好是12个字节。
第三题:
下面这条SQL,该怎么创建联合索引?
SELECT * FROM test WHERE a in (1,2,3) and b > 1;
答案是(a,b)。in条件查询会被转换成等值查询,可以验证一下:

可以看到用到了两个字段的索引。
所以我们在平时做开发,尽量想办法把范围查询转换成in条件查询,效率更高。
> 文章持续更新,可以微信搜一搜「 一灯架构 」第一时间阅读更多技术干货。
三道MySQL联合索引面试题,淘汰80%的面试者,你能答对几道的更多相关文章
- MySQL 联合索引详解
MySQL 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c ...
- mysql 联合索引(转)
http://blog.csdn.net/lmh12506/article/details/8879916 mysql 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中 ...
- SQL Server中的联合主键、聚集索引、非聚集索引、mysql 联合索引
我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...
- MySQL联合索引VS单列索引
MySQL联合索引VS单列索引 以一个一千万数据量的表格为例 1. 建表建索引 USE foo; DROP TABLE IF EXISTS tmp; CREATE TABLE tmp ( id INT ...
- MySQL联合索引最左匹配范例
MySQL联合索引最左匹配范例 参考文章:http://blog.jobbole.com/24006/ 创建示例表. 示例表来自MySQL官方文档: https://dev.mysql.com/doc ...
- [转]mysql联合索引
mysql联合索引 命名规则:表名_字段名1.需要加索引的字段,要在where条件中2.数据量少的字段不需要加索引3.如果where条件中是OR关系,加索引不起作用4.符合最左原则 https:/ ...
- 我说MySQL联合索引遵循最左前缀匹配原则,面试官让我回去等通知
面试官: 我看你的简历上写着精通MySQL,问你个简单的问题,MySQL联合索引有什么特性? 心想,这还不简单,这不是问到我手心里了吗? 听我给你背一遍八股文! 我: MySQL联合索引遵循最左前缀匹 ...
- mysql联合索引详解
联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索 引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c). 可以支持a | a,b ...
- mysql联合索引
命名规则:表名_字段名1.需要加索引的字段,要在where条件中2.数据量少的字段不需要加索引3.如果where条件中是OR关系,加索引不起作用4.符合最左原则 https://segmentfaul ...
随机推荐
- Python数据分析--Numpy常用函数介绍(6)--Numpy中与股票成交量有关的计算
成交量(volume)是投资中一个非常重要的变量,它是指在某一时段内具体的交易数,可以在分时图中绘制,包括日线图.周线图.月线图甚至是5分钟.30分钟.60分钟图中绘制. 股票市场成交量的变化反映了资 ...
- 2.C++标准库函数:getline函数 定界流输入截取函数 -windows编程
引言:今天工作遇到了一个需要按行读取txt文件数据的需求,查询了一下getline()函数,发现这竟然是一个C++的标准库函数,而且设计的很好,特地做一下记录.getline本质是一个定界流输入截取函 ...
- 『忘了再学』Shell流程控制 — 38、while循环和until循环介绍
目录 1.while循环 2.until循环 1.while循环 对while循环来讲,只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止.和for循环的第二种格式for((初始 ...
- idea显示 RunDashboard ,多个启动项时列表显示
在.idea(项目所在文件夹中)下的workspace.xml文件中找到 <component name="RunDashboard"> 标签,然后添加如下节点 < ...
- 我是如何将一个老系统的kafka消费者服务的性能提升近百倍的
☞☞☞ 我是如何将一个老系统的kafka消费者服务的性能提升近百倍的 ☜☜☜ ○○○○○○○○○○○○○○○ 大家好,又见面了~ kafka作为一种高吞吐量的分布式发布订阅消息系统,在业务系统中被广泛 ...
- SpringCloud微服务实战——搭建企业级开发框架(四十三):多租户可配置的电子邮件发送系统设计与实现
在日常生活中,邮件已经被聊天软件.短信等更便捷的信息传送方式代替.但在日常工作中,我们的重要的信息通知等非常有必要去归档追溯,那么邮件就是不可或缺的信息传送渠道.对于我们工作中经常用到的系统,里面 ...
- Chrome实现自动化测试:录制回放网页动作
Chrome 浏览器是真的恐怖,它会把相关的小工具都卷死.从它诞生至今,创造了一个又一个的传奇,现在可以看到基于它的操作系统 chrome os ,还能买到用它做系统的笔记本电脑. 最近,新版本支持录 ...
- ooday04 Java_面向对象_重写_static
方法的重写(override/overriding):重新写.覆盖 发生在父子类中,方法名相同,参数列表相同 重写方法被调用时,看对象的类型------------这是规定,记住就OK 当派生类觉得超 ...
- 彻底理解DDS(信号发生器)的fpga实现(verilog设计代码)
DDS(Direct Digital Synthesis)是一种把一系列数字信号通过D/A转换器转换成模拟信号的数字合成技术. 它有查表法和计算法两种基本合成方法.在这里主要记录DDS查表法的fpga ...
- 输出以二叉树表示的算术表达式(严6.51)--------西工大noj
题解 这道题目说的很诡异,其实没有什么把括号补上....仅仅是先序读入,然后中序输出就行了 代码 #include <stdio.h> #include <stdlib.h> ...