11. Mysql执行原理之索引合并详解

news2024/12/23 12:15:41

MySQL性能调优

  • 1. Intersection合并
    • 1.1 情况一:等值匹配
    • 1.2 情况二:主键列可以是范围匹配
  • 2. Union合并
    • 2.1 情况一:等值匹配
    • 2.2 情况二:主键列可以是范围匹配
    • 2.3 情况三:使用Intersection索引合并的搜索条件
  • 3. Sort-Union合并
  • 4. 联合索引替代Intersection索引合并

本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。

课程内容

1.什么是Intersection合并?

2.什么情况下产生Intersection合并?

3.什么是Union合并?

4.什么情况下产生Union合并?

5.什么是Sort-Union合并?

6.联合索引替代Intersection索引合并

一个select查询语句在执行过程中一般最多能使用一个二级索引来加快查询,即使在where条件中用了多个二级索引。

我们前边说过MySQL在一般情况下执行一个查询时最多只会用到单个二级索引,但存在有特殊情况,在这些特殊情况下也可能在一个查询中使用到多个二级索引,MySQL中这种使用到多个索引来完成一次查询的执行方法称之为:索引合并/index merge,在前面的成本计算中我们说到过这个概念:“我们需要分别分析单独使用这些索引执行查询的成本,最后还要分析是否可能使用到索引合并”。

其实optimizer trace输出的文本中就有这个片段:

在这里插入图片描述

具体的索引合并算法有下面三种

1. Intersection合并

在这里插入图片描述
Intersection翻译过来的意思是交集。这里是说某个查询可以使用多个二级索引,将从多个二级索引中查询到的结果取交集,比方说下边这个查询:

SELECT *FROM order_exp WHERE order_no = 'a'AND expire_time = 'b';

假设这个查询使用Intersection合并的方式执行的话,那这个过程就是这样的:

从idx_order_no二级索引对应的B+树中取出 order_no= 'a’的相关记录。

从idx_insert_time二级索引对应的B+树中取出insert_time= 'b’的相关记录。

二级索引的记录都是由索引列+主键构成的,所以我们可以计算出这两个结果集中id值的交集。

按照上一步生成的id值列表进行回表操作,也就是从聚簇索引中把指定id值的完整用户记录取出来,返回给用户。

为啥不直接使用idx_order_no或者idx_insert_time只根据某个搜索条件去读取一个二级索引,然后回表后再过滤另外一个搜索条件呢?这里要分析一下两种查询执行方式之间需要的成本代价。

只读取一个二级索引的成本:

按照某个搜索条件读取一个二级索引,根据从该二级索引得到的主键值进行回表操作,然后再过滤其他的搜索条件

读取多个二级索引之后取交集成本:

按照不同的搜索条件分别读取不同的二级索引,将从多个二级索引得到的主键值取交集,然后进行回表操作。

虽然读取多个二级索引比读取一个二级索引消耗性能,但是大部分情况下读取二级索引的操作是顺序I/O,而回表操作是随机I/O,所以如果只读取一个二级索引时需要回表的记录数特别多,而读取多个二级索引之后取交集的记录数非常少,当节省的因为回表而造成的性能损耗比访问多个二级索引带来的性能损耗更高时,读取多个二级索引后取交集比只读取一个二级索引的成本更低。

MySQL在某些特定的情况下才可能会使用到Intersection索引合并,哪些情况呢?

1.1 情况一:等值匹配

二级索引列是等值匹配的情况,对于联合索引来说,在联合索引中的每个列都必须等值匹配,不能出现只匹配部分列的情况。

而下边这两个查询就不能进行Intersection索引合并:

SELECT * FROM order_exp WHERE order_no> 'a'AND insert_time = 'a' AND order_status = 'b'AND expire_time = 'c';
SELECT * FROM order_exp WHERE order_no = 'a'AND insert_time = 'a';

第一个查询是因为对order_no进行了范围匹配,第二个查询是因为联合索引u_idx_day_status 中的order_status和 expire_time列并没有出现在搜索条件中,所以这两个查询不能进行Intersection索引合并。

1.2 情况二:主键列可以是范围匹配

比方说下边这个查询可能用到主键和u_idx_day_status进行Intersection索引合并的操作:

SELECT * FROM order_exp WHERE id > 100 AND insert_time = 'a';

对于InnoDB的二级索引来说,记录先是按照索引列进行排序,如果该二级索引是一个联合索引,那么会按照联合索引中的各个列依次排序。而二级索引的用户记录是由索引列+主键构成的,二级索引列的值相同的记录可能会有好多条,这些索引列的值相同的记录又是按照主键的值进行排序的。

所以重点来了,之所以在二级索引列都是等值匹配的情况下才可能使用Intersection '索引合并,是因为只有在这种情况下根据二级索引查询出的结果集是按照主键值排序的。

Intersection索引合并会把从多个二级索引中查询出的主键值求交集,如果从各个二级索引中查询的到的结果集本身就是已经按照主键排好序的,那么求交集的过程就很容易。

假设某个查询使用Intersection索引合并的方式从 idx_order_no和idx_expire_time 这两个二级索引中获取到的主键值分别是:

从 idx_order_no中获取到已经排好序的主键值:1、3、5

从 idx_expire_time中获取到已经排好序的主键值:2、3、4

那么求交集的过程就是这样:逐个取出这两个结果集中最小的主键值,如果两个值相等,则加入最后的父集结果中,否则丢弃当前较小的主键值,再取该丢弃的主键值所在结果集的后一个主键值来比较,直到某个结果集中的主键值用完了,时间复杂度是o(n)。

但是如果从各个二级索引中查询出的结果集并不是按照主键排序的话,那就要先把结果集中的主键值排序完再来做上边的那个过程就比较耗时了。

按照有序的主键值去回表取记录有个专有名词,叫: Rowid Ordered Retrieval,简称ROR。

另外,不仅是多个二级索引之间可以采用intersection索引合并,索引合并也可以有聚簇索引参加,也就是我们上边写的情况二:在搜索条件中有主键的范围匹配的情况下也可以使用Intersection索引合并索引合并。为啥主键这就可以范围匹配了?还是得回到应用场景里:

SELECT * FROM order_exp WHERE id > 100 AND order_no = 'a';

假设这个查询可以采用Intersection索引合并,我们理所当然的以为这个查询会分别按照id >100这个条件从聚簇索引中获取一些记录,在通过order_no= 'a’这个条件从idx_order_no二级索引中获取一些记录,然后再求交集,其实这样就把问题复杂化了,没必要从聚簇索引中获取一次记录。别忘了二级索引的记录中都带有主键值的, 所以可以在从idx_order_no中获取到的主键值上直接运用条件id > 100过滤就行了,这样多简单。所以涉及主键的搜索条件只不过是为了从别的二级索引得到的结果集中过滤记录罢了,是不是等值匹配不重要。

当然,上边说的情况一和情况二只是发生Intersection索引合并的必要条件,不是充分条件。也就是说即使情况一、情况二成立,也不一定发生Intersection索引合并,这得看优化器的心情。优化器只有在单独根据搜索条件从某个二级索引中获取的记录数太多,导致回表开销太大,而通过Intersection索引合并后需要回表的记录数大大减少时才会使用Intersection索引合并。

2. Union合并

我们在写查询语句时经常想把既符合某个搜索条件的记录取出来,也把符合另外的某个搜索条件的记录取出来,我们说这些不同的搜索条件之间是OR关系。有时候OR关系的不同搜索条件会使用到不同的索引,比方说这样:

SELECT * FROM order_exp WHERE order_no = 'a' OR expire_time = 'b'

lntersection是交集的意思,这适用于使用不同索引的搜索条件之间使用AND连接起来的情况;Union是并集的意思,适用于使用不同索引的搜索条件之间使用OR连接起来的情况。与Intersection索引合并类似,MySQL在某些特定的情况下才可能会使用到Union索引合并

2.1 情况一:等值匹配

分析同Intersection合并

2.2 情况二:主键列可以是范围匹配

分析同Intersection合并

2.3 情况三:使用Intersection索引合并的搜索条件

就是搜索条件的某些部分使用Intersection索引合并的方式得到的主键集合和其他方式得到的主键集合取交集,比方说这个查询:

SELECT * FROM order_exp WHERE insert_time = 'a' AND order_status = 'b' AND expire_time = 'c' OR (order_no = 'a'AND expire_time = 'b');

优化器可能采用这样的方式来执行这个查询:

先按照搜索条件 order_no = 'a’AND expire_time = 'b’从索引idx_order_no和idx_expire_time 中使用Intersection索引合并的方式得到一个主键集合。

再按照搜索条件 insert_time = 'a’AND order_status = 'b’AND expire_time = 'c’从联合索引u_idx_day_status中得到另一个主键集合

采用Union索引合并的方式把上述两个主键集合取并集,然后进行回表操作,将结果返回给用户。

当然,查询条件符合了这些情况也不一定就会采用Union索引合并,也得看优化器的心情。优化器只有在单独根据搜索条件从某个二级索引中获取的记录数比较少,通过Union索引合并后进行访问的代价比全表扫描更小时才会使用Union索引合并。

3. Sort-Union合并

Union索引合并的使用条件太苛刻,必须保证各个二级索引列在进行等值匹配的条件下才可能被用到,比方说下边这个查询就无法使用到Union索引合并:

SELECT * FROM order_exp WHERE order_no < 'a' OR expire_time>'z'

这是因为根据order_no< 'a’从 idx_order_no索引中获取的二级索引记录的主键值不是排好序的,根据expire_time> 'z’从 idx_expire_time索引中获取的二级索引记录的主键值也不是排好序的,但是order_no< 'a’和 expire_time> 'z"这两个条件又特别让我们动心,所以我们可以这样:

先根据order_no< 'a’条件从 idx_order_no二级索引中获取记录,并按照记录的主键值进行排序

再根据expire_time> 'z’条件从idx_expire_time二级索引中获取记录,并按照记录的主键值进行排序

因为上述的两个二级索引主键值都是排好序的,剩下的操作和 Union索引合并方式就一样了。

上述这种先按照二级索引记录的主键值进行排序,之后按照Union索引合并方式执行的方式称之为Sort-Union索引合并,很显然,这种Sort-Union索引合并比单纯的Union索引合并多了一步对二级索引记录的主键值排序的过程。

4. 联合索引替代Intersection索引合并

SELECT * FROM order_exp WHERE order_no= 'a' And expire_time= 'z';

这个查询之所以可能使用Intersection索引合并的方式执行,还不是因为idx_order_no和 idx_expire_time是两个单独的B+树索引,要是把这两个列搞一个联合索引,那直接使用这个联合索引就把事情搞定了,何必用啥索引合并呢,就像这样:

ALTER TABLE order_exp drop index idx_order_no, idx_expire_time,add index idx_order_no_expire_time(order_no, expire_time);

这样我们把 idx_order_no, idx_expire_time都干掉,再添加一个联合索引idx_order_no_expire_time,使用这个联合索引进行查询简直是又快又好,既不用多读一棵B+树,也不用合并结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/543867.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

云厂商纷纷降价开启新一轮价格大战,行业竞争加剧未来何从?

5月16日晚间&#xff0c;腾讯云和移动云两大云服务商相继宣布对旗下多款核心产品进行降价。其中&#xff0c;腾讯云降价幅度最高达40%&#xff0c;移动云部分产品直降60%。 而就在20天前4月26日阿里云2023合作伙伴大会上&#xff0c;阿里巴巴CEO张勇率先宣布启动“史上最大规模…

服务(第二十五篇)redis的优化和持久化

持久化的功能&#xff1a;Redis是内存数据库&#xff0c;数据都是存储在内存中&#xff0c;为了避免服务器断电等原因导致Redis进程异常退出后数据的永久丢失&#xff0c;需要定期将Redis中的数据以某种形式&#xff08;数据或命令&#xff09;从内存保存到硬盘&#xff1b;当下…

win7虚拟机无法安装VMwaretools的处理办法(亲测有效!)

最近在学习中用到要安装win7系统&#xff0c;于是我在虚拟机里装了win7系统&#xff0c;但是却发现无法安装VMware tools&#xff0c;最后经多方查证&#xff0c;以下方法可解决&#xff01; 这里提示需要将原始win7升级到win7 SP1版本&#xff0c;可在控制面版——系统和安全…

ChatGPT应用场景巡航之会议纪要

今天我们拿昨天&#xff08;2023年5月17日&#xff09;腾讯发布2023年一季报会议来举例。 首先刚开篇Pony&#xff08;马化腾&#xff09;说的一段话来看下知否AI问答多场景中的会议纪要表现如何&#xff1a; 马化腾&#xff1a;谢谢你&#xff0c;温迪。晚上好。感谢您加入我…

macOS Monterey 12.6.6 (21G646) 正式版发布,ISO、IPSW、PKG 下载

macOS Monterey 12.6.6 (21G646) 正式版发布&#xff0c;ISO、IPSW、PKG 下载 本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持…

【QT 自研上位机 与 STM32F4xx下位机联调>>>can通信测试-基础样例-联合文章】

【QT 自研上位机 与 STM32F103下位机联调>>>通信测试-基础样例-联合文章】 1、概述2、实验环境3、联合文章&#xff08;1&#xff09;对于上位机&#xff0c;可以参照如下例子&#xff08;2&#xff09;对于下位机&#xff0c;可以参照如下例子 4、QT上位机部分第一步…

PCD235A101 3BHE032025R0101功能框图如何在 PLC 中工作?

​ PCD235A101 3BHE032025R0101功能框图如何在 PLC 中工作&#xff1f; ​ 表示功能块和逻辑门的图形编程语言称为功能块图 创建 PLC 时&#xff0c;逻辑门及其在集成逻辑电路中的应用已广为人知。使用专门的绘图应用程序&#xff0c;连接线用于连接功能块编程中的各种符号。…

国内版的ChatGPT模型分享

1、百度的【文心一言】注册地址&#xff1a;点我 这里我很早之前就申请了&#xff0c;所以当前时可以正常使用的&#xff0c;还没有体验的小伙伴&#xff0c;可以现在申请 虽然与ChatGPT还是有一些差距的&#xff0c;但是作为办公助手还是很OK的&#xff01;&#xff01; 而且有…

谷歌升级Find My Device服务,苹果Find My产品市场火爆

谷歌效仿苹果和 Tile 的定位追踪解决方案&#xff0c;在 I / O 2023 开发者大会上宣布升级 Find My Device 平台。 谷歌的 Sameer Samat 宣布&#xff0c;Find My Device 平台在“未来几个月内”支持追踪耳机、平板电脑和其他产品类别。更为重要的是&#xff0c;Find My Devi…

深度学习在图像识别方面的应用

前言 深度学习是一种非常强大的机器学习技术&#xff0c;它在许多领域都有广泛的应用。其中&#xff0c;图像识别是深度学习最成功的应用之一。本文将详细介绍深度学习在图像识别方面的应用。 图像识别的基本步骤 图像识别的基本步骤包括图像预处理、特征提取和分类器。图像预…

airasia Superapp × HMS Core:便捷出行,悦享全程

2023年5月9日-5月11日&#xff0c;HUAWEI P60系列及旗舰产品发布会在欧洲德国、中东非阿联酋、亚太马来西亚、拉美墨西哥陆续举办&#xff0c;为消费者带来高端影像旗舰HUAWEI P60 Pro及系列全场景智能新品。其中在亚太站&#xff0c;还传递了一个重要消息&#xff1a;2023年6月…

Tomcat源码:ProtocolHandler与Endpoint

参考资料&#xff1a; 《Tomcat源码解析系列&#xff08;十一&#xff09;ProtocolHandler》 《Tomcat源码解析系列&#xff08;十二&#xff09;NioEndpoint》 前文&#xff1a; 《Tomcat源码&#xff1a;启动类Bootstrap与Catalina的加载》 《Tomcat源码&#xff1a;容器…

Linux下实现统计文件单词个数和出现次数

本文介绍的是在Linux下实现统计文件单词个数和出现次数&#xff0c;以及实践过程中遇到的gcc编译器不匹配问题 一、实现文件单词个数统计 #include <stdio.h>#define IN_Word 1 #define OUT_Word 0 #define INIT OUT_Wordint splite(char c){if ((c ) || (c\n) || (c\t…

上海丨阿里云 Serverless 技术实战营邀你来玩!

活动简介 本次沙龙深度探讨 “Serverless 在中国企业的落地和开发者实操” 主题&#xff0c;我们特别邀请了来自阿里云一线技术专家&#xff0c;分享当前 Serverless 趋势和落地实践过程中的挑战和机遇&#xff1b;带来数据库 Serverless 技术架构及应用实践&#xff1b;浅析云…

地铁之家—车辆段

城市轨道交通列车也有一个家——车辆段&#xff0c;它通常由停车区、维修区和清洗区等组成&#xff0c;用于停放、维修保养。 一、地铁车辆段和停车场有何不同&#xff1f; 停车场在管理上一般附属于主要车辆段&#xff0c;规模较小&#xff0c;功能上可以实现车辆的运用管理…

如何进行MySQL漏洞扫描

MySQL是一款广泛使用的关系型数据库管理系统&#xff0c;但由于其复杂的结构和功能&#xff0c;也存在不少安全漏洞&#xff0c;容易被黑客攻击。为了解决这些安全问题&#xff0c;进行MySQL漏洞扫描是必要的。那么MySQL怎么进行漏洞扫描?如何进行漏洞扫描?接下来就让小编带大…

ChatGPT为什么能生成图片?

有小伙伴说我想用ChatGPT生成图片怎么操作&#xff0c;ChatGPT怎么画图等 这里阐明一下&#xff0c;ChatGPT是不能够做到画图的 因为它是一种自然语言处理模型&#xff0c;主要用于处理文本和语言相关的任务&#xff0c;例如问答、对话、翻译等。但是&#xff0c;我们可以使用C…

技术干货|如何利用 ChunJun 实现数据离线同步?

ChunJun 是⼀款稳定、易⽤、⾼效、批流⼀体的数据集成框架&#xff0c;基于计算引擎 Flink 实现多种异构数据源之间的数据同步与计算。ChunJun 可以把不同来源、格式、特点性质的数据在逻辑上或物理上有机地集中&#xff0c;从⽽为企业提供全⾯的数据共享&#xff0c;目前已在上…

针对电子企业的仓储需求,提出WMS仓储管理系统解决方案

随着电子行业的快速发展&#xff0c;仓储管理已经成为电子企业日常运营中不可或缺的一环。然而&#xff0c;由于缺乏有效的仓储管理系统&#xff0c;电子企业经常面临库存不准确、库存滞销等问题。这就是电子企业仓储管理面临的严重问题&#xff0c;引出了需要提出一套有效的仓…

【每日一题Day211】LC1079活字印刷 | 回溯 计数dp

活字印刷【LC1079】 你有一套活字字模 tiles&#xff0c;其中每个字模上都刻有一个字母 tiles[i]。返回你可以印出的非空字母序列的数目。 **注意&#xff1a;**本题中&#xff0c;每个活字字模只能使用一次。 我反正是写的相当暴力 计数回溯 思路&#xff1a; 为了构成不同的…