三道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 ...
随机推荐
- 【Github】 Github访问不是私密连接问题
前言 GitHub是一个软件项目的托管平台,是我们经常需要访问的,我原本在学校时候虽然网速比较慢,但是还以能够满足一些代码下载和上传的,在暑假回到家,再去访问的时候就出现了不能访问的问题. 问题描述 ...
- 自嗨ReentrantReadWriteLock
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util ...
- 2022giao考游记
Day -12: 今年高考准备去考着玩玩,考前心态十分稳健.~~毕竟我才高一/cy~~ 这次高考我倒是没啥目标,主要是来试试水,感受一下高考的氛围,体会一下自己和高三应届生们的水平的差距.也算是丰富自 ...
- React技巧之处理tab页关闭事件
原文链接:https://bobbyhadz.com/blog/react-handle-tab-close-event 作者:Borislav Hadzhiev 正文从这开始~ 总览 在React中 ...
- Navicat中查询mysql版本
SELECT VERSION( ) FROM DUAL
- .Net之延迟队列
介绍 具有队列的特性,再给它附加一个延迟消费队列消息的功能,也就是说可以指定队列中的消息在哪个时间点被消费. 使用场景 延时队列在项目中的应用还是比较多的,尤其像电商类平台: 订单成功后,在30分钟内 ...
- Tomcat深入浅出(一)
一.Tomcat简介 我们下载好Tomcat后需要配置一下Java环境:如果打开出现闪退得情况,首先是jdk 同时配置JRE_HOME Tomcat的一些关键目录: /bin:存放用于启动及关闭的文件 ...
- 如何将 DevSecOps 引入企业?
前 言 现如今,大部分企业已经在内部实现了 DevOps 实践.DevOps 为团队提供了交付可靠软件和快速更新的方法论.这种方法让团队更专注于质量而不是将时间浪费在运维上.然而,结果是,安全实践往往 ...
- python虚拟环境(python+conda)
python的不同虚拟环境就相当于在电脑上装了很多个python.下面写python创建虚拟环境.conda创建虚拟环境和在pycharm中配置一下. python -m venv (要创虚拟环境的路 ...
- 自动登录token过期问题
之前遇到的一个也不算棘手的问题,自动登录本地存储了token却无法登录到主页. 先说一下我自动登录的思路:在用户登录成功时,将 token 存入 cookie :当用户下次来到本网站,读取 cooki ...