前言

同事去面试被问到了单个索引 和 组合索引谁更快,往往不经意的知识就有可能会被问到,这里以 MySQL 为例,相信被问到这个问题的时候,很多人也不清楚谁比较快,什么情况下会快,下面就让我为大家分析两者的主要区别,供大家参考学习。

首先我们创建第一张 user1 表为组合索引,如下所示:

第二种表为单列索引,如下所示:

创建完表之后我们开始测试

测试单个索引

条件 user_name and sex and student_job_no

EXPLAIN select user_name from user2 where user_name = "张三" and sex = "1" and student_job_no = 'HSBZR01032'

我们发现 3 个单列索引只用上了一个,位置在第三个的,而其他两个索引都没有用到,这是为什么呢?

因为这里涉及到了 MySQL 优化器的优化策略,当多条件组合查询时,优化器会评估用哪个条件的索引效率最高!它会选择最佳的索引去使用,也就是说,使用 user_name 、sex 、student_job_no 这个三个索引查询 ,优化器会判断使用 student_job_no 这一个索引能最高效完成本次的查询,所以 explain 显示的的 key 为 student_job_no 。

条件 sex and student_job_no

EXPLAIN select user_name from user2 where sex = "1" and student_job_no = 'HSBZR01032'


此处条件只有 student_job_no 生效,和前面的一样。

条件 user_name and sex

EXPLAIN select user_name,sex from user2 where user_name = "张三" and sex = "1"


此处条件只有 user_name 生效。

测试组合索引

条件 user_name

EXPLAIN select * from user1 where user_name = "张三"


通过 user_name 查询索引生效。

条件 sex

EXPLAIN select * from user1 where sex = "1"


通过 sex 查询索引无效。

条件 student_job_no

EXPLAIN select * from user1 where student_job_no = "HSBZR01032"


通过 student_job_no 查询索引无效。

条件 user_name and student_job_no

EXPLAIN select * from user1 where user_name ="张三" and student_job_no = "HSBZR01032"


通过 user_name and student_job_no 查询索引有效。

条件 sex and student_job_no

EXPLAIN select * from user1 where sex ="1" and student_job_no = "HSBZR01032"


通过 sex and student_job_no 查询索引无效。

user_name and sex and student_job_no

EXPLAIN select * from user1 where user_name ="张三" and sex ="1" and student_job_no = "HSBZR01032"


通过 user_name and sex and student_job_no 查询索引依然有效。

组合索引的本质

我这里创建了组合索引,为什么有的组合索引可以,有的不可以呢。

这是因为创建(user_name , sex , student_job_no )组合索引时,其实是相当于分别建立了下面三组组合索引:

[ user_name ,sex ,student_job_no ] 、[ user_name ,sex ]、[ user_name ]

这三个组合索引当中,为什么没有 sex ,student_job_no 等这样的组合索引呢?这是因为 MySQL 组合索引“最左前缀”的结果。

最左前缀

简单的理解就是只从最左边的开始组合。组合索引的第一个字段必须出现在查询组句中,并且不能跳跃,这个索引才会被用到,因此并不是只要包含这三列的查询都会用到该组合索引。

下面的几个 SQL 就会用到组合索引:

select * from user1 where user_name="张三" AND sex="1"
select * from user1 where user_name="张三"

而下面几个则不会用到:

select * from user1 where sex ="1" and student_job_no = "HSBZR01032"
select * from user1 where student_job_no = "HSBZR01032"

这里需要注意一点就是:索引的字段可以是任意顺序的

比如以下的 SQL 都会使用到索引:

EXPLAIN select * from user1 where user_name ="张三" and sex ="1"
EXPLAIN select * from user1 where sex ="1" and user_name ="张三"

MySQL创建联合索引的规则是首先会对联合合索引的最左边的,也就是第一个字段的数据进行排序,在第一个字段的排序基础上,然后再对后面第二个字段进行排序。

查询时间

单列索引时间:

select * from user2 where user_name = "张三" and sex = "1" and student_job_no = 'HSBZR01032'
受影响的行: 0
时间: 0.004s

组合索引时间:

select * from user1 where user_name ="张三" and sex ="1" and student_job_no = "HSBZR01032"
受影响的行: 0
时间: 0.005s

给三个列加上索引,不管是单列索引还是组合索引,查询时间都是相差不大。

但是如果组合索引没有按照 “最左前缀” 规则实现,比如以下 SQL :

select * from user1 where  sex ="1" and student_job_no = "HSBZR01032"
受影响的行: 0
时间: 0.046s

查询时间会比单列索引时间要长。

组合索引优势

组合索引 比对每个列分别建索引更有优势,因为索引建立得越多就越占磁盘空间,在更新数据的时候速度会更慢。另外建立多列索引时,顺序也是需要注意的,应该将严格的索引放在前面,这样筛选的力度会更大,效率更高。

单个索引和组合索引(联合索引)谁效率高相关推荐

  1. mysql联合索引怎么存储_联合索引在B+树上的存储结构及数据查找方式

    能坚持别人不能坚持的,才能拥有别人未曾拥有的. 关注编程大道公众号,让我们一同坚持心中所想,一起成长!! 引言 上一篇文章<MySQL索引那些事>主要讲了MySQL索引的底层原理,且对比了 ...

  2. mysql教程联合索引_MySQL中的联合索引学习教程

    联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c). 可以支持a | a,b| ...

  3. mysql中联合索引abc 使用bac_mysql 联合索引

    mysql 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c). ...

  4. mysql索引(五)联合索引

    Mysql索引大概有五种类型: 普通索引(INDEX):最基本的索引,没有任何限制 唯一索引(UNIQUE):与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值. 主 ...

  5. mysql联合索引like_MySQL全文索引、联合索引、like查询、json查询速度大比拼

    查询背景 有一个表tmp_test_course大概有10万条记录,然后有个json字段叫outline,存了一对多关系(保存了多个编码,例如jy1577683381775) 我们需要在这10万条数据 ...

  6. 《MySQL学习》 索引 下 覆盖索引,MRR,联合索引

    一. 覆盖索引 有一张表T1,它的建表语句如下 mysql> create table T1 ( ID int primary key, k int NOT NULL DEFAULT 0, s ...

  7. MySQL复合索引 in查询,mysql 联合索引 in查询是否生效

    这篇文章主要讲的是使用in查询,联合索引是否会生效的问题 首先简单说一下联合索引:联合索引又叫复合索引,是由表中的几个列联合组成的索引.联合索引生效需满足最左前缀原则,即如果联合索引列为a,b,c三列 ...

  8. mysql联合索引不按顺序_mysql联合索引的使用以及sql执行的过程顺序

    例如新增了一个联合索引 abc, 我写一条sql select * from table1 where a=1 and b=2 and c=2; 这样3个字段都是可以使用联合索引的.3者调换任意位置, ...

  9. mysql联合索引单列索引效率_联合索引和单个索引使用注意事项

    联合索引: 通俗理解: 利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引.复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名 ...

  10. 联合索引(复合索引)和单个索引

    背景:  为了提高数据库效率,建索引是家常便饭:那么当查询条件为2个及以上时,我们是创建多个单列索引还是创建一个联合索引好呢?他们之间的区别是什么?哪个效率高呢?我在这里详细测试分析下. 一.联合索引 ...

最新文章

  1. Angular--TypeScript finalize 方法
  2. linux下sort命令使用详解---linux将文本文件内容加以排序命令
  3. Python处理mat文件的三种方式
  4. 机器学习系列(5)_从白富美相亲名单看特征选择与预处理(上)
  5. 矩阵快速幂 学习笔记
  6. 比亚迪定薪后多久给offer_比亚迪车主给爱车做四门隔音,没想到两年后肠子都悔青...
  7. 用户体验设计的五个原则(转)
  8. termux apache php,要啥自行车之Termux:将我们的(Android)安卓手机打造成全能的服务器...
  9. 计算机使用技巧爆文,自媒体干货篇:利用这个小技巧可以五分钟之内写好一篇爆文!...
  10. linux动态库加载RPATH,RUNPATH
  11. hibernate访问效率相关
  12. php 字符串含有下划线,PHP-我的会话ID中有下划线
  13. HTML CSS 响应式-菜单
  14. Postman界面介绍及实例(转)
  15. Python运行时报错 ModuleNotFoundError: No module named ‘exceptions‘
  16. fft 相位谱_数值积分——使用FFT来降低计算量
  17. oracle 虚拟机安装mac os,oracle vm virtualbox虚拟机安装mac os x详细图解
  18. 给大学生们推荐几个商城毕业设计课题,大家可以看看演示借鉴下
  19. 伏羲六十四卦+36D
  20. 电脑基础:键盘F1~F12你会用吗?天天都看到,但会用的真没几个!

热门文章

  1. 东南亚金融服务商Pundi X正式加入 Achain 生态
  2. Revit 2019注册机
  3. 两台android相互ADB实现一台安卓手机给另一台安卓手机ADB
  4. 《我奋斗了18年才和你坐在一起喝咖啡》,而我奋斗了18年,不是为了和你一起喝咖啡(转载)...
  5. 如何利用PS做文字拼接海报
  6. 【学习笔记】单总线协议的典型代表:DS18B20
  7. 解决:ORA-06502: PL/SQL: numeric or value error: NULL index table key value
  8. 哪些软件可以做国外问卷调查
  9. 互联网与物联网有什么区别?
  10. c语言判断闰年并输出该月天数,C语言宏定义实现闰年判断并输出指定月的天数...