栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

六、索引——单表访问和连接访问

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

六、索引——单表访问和连接访问

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录
  • 一、单表访问方法?
  • 二、对单表查询的优化
    • 2.1 MRR——多范围读取
    • 2.2 索引合并
      • 2.2.1Intersection 索引 :交集索引
      • 2.2.2 Union索引合并 :并集索引
      • 2.2.3 Sort—Union索引合并
  • 三 、连接的原理
    • 3.1 笛卡尔积
    • 3.2 连接的过程
    • 3.3 内连接和外连接
  • 四 连接的原理

一、单表访问方法?

Mysql sever 有一个称为优化器的模块,mysql查询语句对一条查询语句进行语法分析之后,就会将其交给优化器来优化,优化的结果就是生成一个所谓的执行计划,这个执行计划表明了应该使用哪些索引进行查询、表与表之间的连接顺序是啥样的,但是“查询优化”则这个主题有点大,那么今天就从最简单的单表查询下手

访问方法:mysql把执行查询语句的方式叫做访问方法或访问类型
1、const:通过主键或者唯一二级索引与常数进行等值比较
SELECt * FROM single_table where key2 =’a’; key2是唯一索引的列
2、ref:搜索条件为普通的二级索引
SELECt * FROM single_table where key1 =’a’; key1为普通的二级索引
3、ref_or_null:使用二级索引而不是全表扫描,对应的扫描区间是[‘a’,’a’]和[null,null]
SELECt * FROM single_table where key1 =’a’ or key1 is null;
B+数索引中,值为null的会放在索引的最左边
4、range :使用索引执行查询时扫描区间为若干个单点扫描区间或范围扫描
SELECt * FROM single_table where key2 in (132,21) or (key2 >39 and key <89)
5、index:
直接扫描全部的二级索引但不回表的
扫描聚簇索引的加了order by
6、all :直接扫描聚簇索引。

二、对单表查询的优化 2.1 MRR——多范围读取

就是先读取一部分二级索引,对他们按照主键进行排序后,再进行回表操作。这个其实是用二级索引查找到主键后,因为主键在二级索引中又不是顺序的,通常,每次从二级索引查到一条记录就进行回表操作,进入聚簇索引后,就会发生随机io,mysql为了减少随机io的发生,就会读取多个记录后,再按照主键的顺序排序回表。

2.2 索引合并

一般情况下,mysql只会为单个索引生成扫描区间,但是还存在特殊的情况,mysql还可能为多个索引生成扫描区间,这个方法叫做index merge
索引合并有三种方式

2.2.1Intersection 索引 :交集索引

SELECt * FROM single_table WHERe key1=’a’ AND key2=’b’
因为key1和key2上面都有索引,因此优化器再选择执行计划的时候会考虑一下方案
①方案一:全表扫描,这个不多数了,讲烂了
②方案二:使用key1 列的索引,此时扫描区间就是[‘a’,’a’],对于获取到的每条危机索引记录,根据它的主键值进行回表操作,获取完整的用户记录,再判断key2=’b’的条件是否满足,将满足的插入结果集中。
③方案三:使用key2列的索引,此时扫描区间就是[‘b’,’b’],对于获取到的每条危机索引记录,根据它的主键值进行回表操作,获取完整的用户记录,再判断key1=’a’的条件是否满足,将满足的插入结果集中。
④方案四:在key1中扫描[‘a’,’a’]的二级索引记录,在key2中扫描[‘b’,’b’]的二级索引记录,然后在两者的操作结果中取交集,拿交集部分进行回表操作
交集索引的使用前提:扫描出来的二级索引记录必须是按照主键值排序的,主要是两个有序集合取交集比两个无序集合快,减少随机IO

2.2.2 Union索引合并 :并集索引

SELECt * FROM single_table WHERe key1=’a’ OR key2=’b’
意思是取连个二级索引的各自的用户记录,取并集再对并集的结果去重,然后对结果集进行回表,这个同样要求,三个二级索引的记录必须是按照主键进行排序的

2.2.3 Sort—Union索引合并

Sort—Union索引合并其实是对Union索引合并的优化,前面的要求太苛刻,必须扫描的结果按主键从小到大排序,这个是把扫描到的记录按照主键从小到大进行排序,再取并集,然后去重,回表

三 、连接的原理

本质上连接就是把各个表中的记录都取出来进行依次匹配,并把匹配后的组合发送给客户端。

3.1 笛卡尔积


这个过程就是两个表的记录连接起来组成一个更大的记录,所以这个查询叫做连接查询。如果连接查询的结果集包含了一个表中的每一条记录与另一个表中的每一条记录相匹配的组合,那么这样的结果集就叫做笛卡尔积。

3.2 连接的过程

1、首先确定哪个是驱动表
2、从驱动表中获取每一条记录到被驱动表中根据连接条件依次查找
匹配的记录。
注意:两个表的连接中,驱动表只需要被访问一次,被驱动表的访问次数由驱动表的结果集决定。
通常情况下可以理解为,驱动表查一条结果,就去被驱动表匹配。但是实际上mysql引入了join buffer缓冲区,就是把多条驱动表的查询结果,放到内存的join buffer中,取被驱动表的一条数据与join buffer中的多条被驱动表的数据进行匹配,这样可以减少对被驱动表的访问次数,进而减少IO次数,这也是一种优化思想。

3.3 内连接和外连接

1、外连接分为左外连接(left join)和右外连接(right join)
①对于left join来说,左表是驱动表,就是left join 左边的表是驱动表,查询时,不考虑where过滤时,驱动表取全数据,对于被驱动表不匹配的记录用NULL补充。
②对于right join来说,右表是驱动表,就是right join 右边的表是驱动表,查询时,不考虑where过滤时,驱动表取全数据,对于被驱动表不匹配的记录用NULL补充。
2、内连接
内连接的驱动表需要由优化器来确定,优化器分别分析哪个表作为驱动的执行成本,选择成本最低的(通常小表驱动大表)。两个表的查询结果是两个表的交集,也就是说对于驱动表的结果集,如果通过连接条件在被驱动表中找不到匹配的记录,那么这条结果集就会丢掉。

四 连接的原理

一句话,连接其实就是嵌套循环
SELECt b.c1 FROM table_1 a LEFT JOIIN table_2 b on a.c2=b.c2
取a中所有的数据作为结果集,去b中循环匹配,在符合a.c2=b.c
2的记录中,取b.c1作为我们查询的结果集返回客户端
但是,一条一条的取a中的数据到b中匹配实在是太慢了,如果a的结果集小的话还好,多的话效率太低了,因此引入了join buffer (连接缓冲区)把驱动表a中取到的多条记录放到join buffer中,然后取被驱动表的一条的记录与join buffer中a的多条记录匹配然后筛选结果,这样就可以有效的减少对被驱动表b的访问,进而减少了IO次数(访问b的次数越多,加载页的次数就越多)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/831224.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号