目录

  • Mysql优化(出自官方文档) - 第二篇

    • 1 关于Nested Loop Join的相关知识

Mysql优化(出自官方文档) - 第二篇

1 关于Nested Loop Join的相关知识

1.1 相关概念和算法

Mysql在实现join的时候,采用的Nested Loop Join技术,join的方式还有其他两种:Hash JoinSortMergeJoin ,Mysql处于逻辑实现统一的角度,只实现了Nested Loop Join,假设有t1, t2, t3三张表,EXPLAIN优化的结果为:

Table   Join Type
t1      range
t2      ref
t3      ALL

那么其Join的方式可以用下面的为代表来表示:

for each row in t1 matching range {for each row in t2 matching reference key {for each row in t3 {if row satisfies join conditions, send to client}}
}

为了减少内表的IO,Mysql又引入了NestedLoopJoin的一个变种,叫做:Block Nested-Loop Join,简称为BNL,简单理解就是NestedLoopJoin With Buffer,为每一个join维护一个Join Buffer,对于外层循环,每次将扫描的行放入到Buffer中,内表直接对Buffer中的行进行匹配操作,对应的伪代码如下:

for each row in t1 matching range {for each row in t2 matching reference key {store used columns from t1, t2 in join bufferif buffer is full {for each row in t3 {for each t1, t2 combination in join buffer {if row satisfies join conditions, send to client}}empty join buffer}}
}if buffer is not empty {for each row in t3 {for each t1, t2 combination in join buffer {if row satisfies join conditions, send to client}}
}
1.2 一些优化
  • 在Join语句中,除了on 语句后面的条件外,如果还存在where语句,假设有三张表t1, t2, t3,如下面的格式:

    select * from (t1,t2) on P1(t1,t2) inner join t3 on P2(t2,t3) where C1(t1) and C2(t2) and C3(t3);

    inner join的伪代码如下所示:

    FOR each row t1 in T1 such that C1(t1) {FOR each row t2 in T2 such that P1(t1,t2) AND C2(t2)  {FOR each row t3 in T3 such that P2(t2,t3) AND C3(t3) {IF P(t1,t2,t3) {t:=t1||t2||t3; OUTPUT t;}}}
    }

    Mysql会采用条件下推的优化方式,提前将where的条件限制在inner join的循环里面,这样子,如果C1的条件非常严苛,那么可以避免大量对t2, t3表的IO操作。需要注意的是:这种优化方式可能并不适用于outer joinouter joinwhere提前会导致不同的结果。

  • outer join优化

    • 对于left join,如果对于generated NULL row, 后面的where条件始终为false, 那么,这个left join可以被安全的转换为inner join,如下面的语句所示,假设t1.column1始终为NULL

      SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;

      那么这条语句可被转换为inner join

      SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;

      解释:之所以会有这样的转换, 是因为这样做t2便不需要进行全表扫描,只需要扫描出column2 = 5的行。

    • 有时候,在prepare阶段,一些琐碎的条件可以直接被移除掉(特指Mysql8.0.14+的版本),而不是在优化器里面在进行移除,提前移除这些条件,可以让优化器尽可能的把left join转换为inner join,比如以下语句:

      SELECT * FROM t1 LEFT JOIN t2 ON condition_1 WHERE condition_2 OR 0 = 1

      0 = 1始终为false,因此可以直接移除掉,移除后的结果:

      SELECT * FROM t1 LEFT JOIN t2 ON condition_1 where condition_2

      此时,优化器便可以根据实际情况将该语句优化为inner join(假设按照上一个规则优化):

      SELECT * FROM t1 JOIN t2 WHERE condition_1 AND condition_2
  • outer join一些简化措施(重写或者转换)

    • 大多数情况下,right join会在解析阶段直接被转换为left join,如下所示:

      (T1, ...) RIGHT JOIN (T2, ...) ON P(T1, ..., T2, ...)

      转换为的结果为:

      (T2, ...) LEFT JOIN (T1, ...) ON P(T1, ..., T2, ...)
    • 有时候,当join带有where条件时,并且where条件里面首先对inner table进行访问,那么这个时候,优化器将很难对其进行优化,比如下面的例子:

      SELECT * T1 LEFT JOIN T2 ON P1(T1,T2)WHERE P(T1,T2) AND R(T2)

      此时,Mysql会对where条件进行null-rejected判断,如果判断成功,那么outer join就可以安全的被转换为inner join,需要注意的是,进行null-rejected判断的对象必须在内表上,原理很简单,因为对于outer join,如果内表没有匹配到的行,会进行null-complemented(对应的内表所有行被设置为NULL),所以,如果此时where条件对于内表的判断始终为false,那么null-complemented的行将会被过滤掉,此时``outer join的结果将等价于inner join的结果,对于下面的例子:

      T1 LEFT JOIN T2 ON T1.A=T2.A

      null-rejected的条件包括(t2的列会被设置为NULL):

      T2.B IS NOT NULL
      T2.B > 3
      T2.C <= T1.C
      T2.B < 2 OR T2.C > 1

      下面的条件不属于null-rejected,因为下面的条件对于null-complemented行可能为真:

      T2.B IS NULL
      T1.B < 3 OR T2.B IS NOT NULL
      T1.B < 3 OR T2.B > 3

      举例说明,比如下面的语句:

      SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.ALEFT JOIN T3 ON T3.B=T1.BWHERE T3.C > 0

      可以判断出,T3.C > 0是一个典型的null-rejected条件,因此该语句可以被直接的转换为:

      SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.AINNER JOIN T3 ON T3.B=T1.BWHERE T3.C > 0

      再来看一个更加复杂的例子

      SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.ALEFT JOIN T3 ON T3.B=T2.BWHERE T3.C > 0

      与第一个例子唯一的趋避额就是T2T3 join的条件不同,此时join的对象变成了T3.B = T2.B,类似于第一个例子,上述语句可以直接转换为:

      SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.AINNER JOIN T3 ON T3.B=T2.BWHERE T3.C > 0

      在Mysql中,inner joincross join带on的版本,上面这条语句和下面是等价的:

      SELECT * FROM (T1 LEFT JOIN T2 ON T2.A=T1.A), T3WHERE T3.C > 0 AND T3.B=T2.B

      对于最外层的T1T2,可以看到where条件里面的T3.B = T2.B又是一个null-rejected条件,因此,外层的join也可以被直接优化为:

      SELECT * FROM (T1 INNER JOIN T2 ON T2.A=T1.A), T3WHERE T3.C > 0 AND T3.B=T2.B

      经过上面的优化过程,最终的语句已经没有了outer join,可以大幅度提高join的效率,因此根据该优化规则,我们写join的时候,也可以有效的利用这种优化方式。

转载于:https://www.cnblogs.com/seancheer/p/11213836.html

Mysql优化(出自官方文档) - 第二篇相关推荐

  1. Unity 优化翻译官方文档(二) ------ 平台特定覆盖的纹理压缩格式

    官方文档 : https://docs.unity3d.com/Manual/class-TextureImporterOverride.html 虽然Unity支持许多常见的图像格式作为导入纹理的源 ...

  2. storm mysql trident_Apache Storm 官方文档 —— Trident 教程

    Trident 是 Storm 的一种高度抽象的实时计算模型,它可以将高吞吐量(每秒百万级)数据输入.有状态的流式处理与低延时的分布式查询无缝结合起来.如果你了解 Pig 或者 Cascading 这 ...

  3. Xtend官方文档——第二部分(一)

    第二章 语言文档参考(一) 第一节  Java互操作性 Xtend像Java一样,是一种静态类型的语言.实际上,它完全支持Java的类型系统,包括基本类型,如int或者boolean.数组以及类路径上 ...

  4. 看懂mysql执行计划--官方文档

    原文地址:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html 9.8.2 EXPLAIN Output Format The EXP ...

  5. Unity优化翻译官方文档(六) ------ CPU Usage Profiler

    官网地址 : https://docs.unity3d.com/Manual/ProfilerCPU.html CPU使用分析器显示在您的游戏中花费的时间.当它被选中时,下窗格将显示所选帧的分层时间数 ...

  6. Unity 优化翻译官方文档(三) ------ Animation Clips

    动画剪辑是Unity动画中最小的组成部分.它们代表了一个孤立的运动,如RunLeft.跳转或爬行,并且可以以各种方式进行操作和组合,以产生生动的最终结果(参见动画状态机.动画控制器控制器或混合树).您 ...

  7. MySQL8.0.28安装教程全程参考MySQL官方文档

    MySQL8.0.28详细安装教程.提供了Windows10下安装MariaDB与MySQL8.0同时共存的方法,以及Linux发行版Redhat7系列安装MySQL8.0详细教程.Windows10 ...

  8. mysql中括号_手把手教你看MySQL官方文档

    前言: 在学习和使用MySQL的过程中,难免会遇到各种问题.不知道当你遇到相关问题时会怎么做,我在工作或写文章的过程中,遇到不懂或需要求证的问题时通常会去查阅官方文档.慢慢的,阅读文档也有了一些经验, ...

  9. Sklearn官方文档中文整理6——交叉分解,朴素贝叶斯和决策树篇

    Sklearn官方文档中文整理6--交叉分解,朴素贝叶斯和决策树篇 1. 监督学习 1.8. 交叉分解[cross_decomposition.PLSRegression,cross_decompos ...

  10. MySQL MHA高可用架构官方文档全文翻译

    目录 MHA项目官方github地址 关于MHA 概述 主故障切换的难点 现有的解决方案和问题 MHA的架构 MHA的优势 使用案例 其他高可用解决方案和问题 纯手动解决 单主单从 一个主节点.一个备 ...

最新文章

  1. MySQL查询语句的45道练习
  2. mencoder视频旋转
  3. 深度学习-TF函数-layers.concatenate用法 numpy数组维度
  4. 晶振,数字电路的心脏~
  5. VirtualBox 扩展虚拟硬盘容量
  6. vue 导出_Vue核心知识:8.3 vuex在vue-cli中的应用,文件之间的导出与引入
  7. js获取时间(本周、本季度、本月..)
  8. FreeRTOS(2)---学习FreeRTOS前的准备工作
  9. python字典类型可迭代_核心数据类型--字典
  10. vue为app做h5页面,如何做到同域名对应不同版本的h5代码
  11. ipv6单播地址包括哪两种类型_探秘联接|技术小课堂之BRAS设备IPv6地址分配方式...
  12. monkey命令_Monkey 稳定性测试
  13. 实用供暖通风空调设计手册 第三版_实用供热空调设计手册第三版即将出版随想...
  14. 游戏中常见英语词汇,做游戏的,玩游戏总是要碰到的
  15. 硬件仿真加速器(emulator)
  16. 宇枫资本投资理财投资入门与技巧
  17. 获取“今日头条”西瓜视频
  18. 相濡以沫,不如相忘于江湖...
  19. 系统调优之四大天王——快来瞧瞧~
  20. thymeleaf 修改css,用thymeleaf设置CSS样式属性

热门文章

  1. Java的注解和反射
  2. 文件存储形式的通讯录
  3. JavaEE学习--javascript中的正则表达式
  4. Flutter实战之底部导航栏 BottomNavigation
  5. 打造AS酷炫dimens适配插件
  6. 老码农最后都去哪了?
  7. w8的计算机管理打不开,Win8.1系统打不开控制面板怎么办 win8.1无法打开控制面板如何解决...
  8. linux怎么安装网卡驱动固件,Linux网卡驱动的安装方式
  9. mysql 数据字典详解_MySQL8功能详解——数据字典
  10. pygame放大图片_使用Pygame进行游戏开发(3)--绘图