IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MySQL·源码分析·null reject谓词 -> 正文阅读

[大数据]MySQL·源码分析·null reject谓词

Note:
本文背景大部分描述来自于 MySQL 官网,感兴趣的可以看原文描述
outer join simple

背景

outer join 的简化

  • right JOIN 的处理

MySQL 通常在解析阶段,就将 RIGHT JOIN 转换为 LEFT JOIN 的等效查询,例如:

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

等价于

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

JOIN 的驱动表顺序变成在,T1 INNER JOIN t2 ON P(T1,T2) 变成 T1, T2, P(T1, T2)
但优化器对于驱动表顺序的选择依然有限,仅能考虑 T1 在前的情况,可以进一步尝试

  • inner JOIN 转换

例如:

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

如果该 SQL 按着此顺序执行,优化器只能按着 T1 驱动 T2 顺序执行,可可能会产生非常低效率的执行计划。

相反,如果 WHERE 条件是一个 null-rejected 的谓词,MySQL 可以将此类查询转换为一个非 outer join(inner join).

一个条件如果对于所有 NULL-complemented 的行来说,都会被评估为 FALSE 或者 UNKWON,则该条件对于 outer join 而言是 null-rejected.

null-rejected

一个条件如果对于所有 NULL-complemented 的行来说,都会被评估为 FALSE 或者 UNKWON,则该条件对于 outer join 而言是 null-rejected.

例如,对于以下外部连接:

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

以下条件会被视为 null-rejected,因为对于任何一个 NULL-complemented 的行,此条件都不可能为 true

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

而以下条件不会被视为 null-rejected,因为对于任何一个 NULL-complemented 的行,此条件可能为 true

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

一个条件对于 outer join 而言,为 null-rejected 的通用规则为:

  • It is of the form A IS NOT NULL, where A is an attribute of any of
    the inner tables
  • It is a predicate containing a reference to an inner table that evaluates to UNKNOWN when one of its arguments is NULL
  • It is a conjunction containing a null-rejected condition as a conjunct
  • It is a disjunction of null-rejected conditions

一个条件对于 outer join 查询中的一个 outer join 可能是 null-rejected 但对于另一个不是 null-rejeced.

例如,下面 WHERE 条件对于第二个 outer join 是 null-rejected 的,但对第一个 outer join 不是:

SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.A LEFT JOIN T3 ON T3.B=T1.B WHERE T3.C > 0如果一个 WHERE 条件对于一个 outer join 而言是一个 null-rejected 的话,则 outer join 可以转换为 inner join.
例如,上述 SQL 可以转换为:

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

这样,原有仅能考虑 T1,T2,T3 的联接顺序就可以再额外考虑 T3,T1,T2 的联接方式。

进一步优化

一个外连接操作的转换可能会触发另一个外连接操作的转换。因此,查询:

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

首先转换为查询:

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

这相当于查询:

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

剩余的外连接操作也可以用内连接代替,因为条件 T3.B=T2.B 被拒绝为空。这会导致查询完全没有外部连接:

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

有时优化器成功替换了嵌入外连接操作,但无法转换嵌入外连接。以下查询:

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

转换为:

SELECT * FROM T1 LEFT JOIN 
                 (T2 INNER JOIN T3 ON T3.B=T2.B) 
                 ON T2.A=T1.A
WHERE T3.C > 0

只能将其重写为仍包含嵌入外连接操作的表单:

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

任何在查询中转换嵌入外连接操作的尝试都必须考虑嵌入外连接的连接条件和 WHERE 条件。在这个查询中,嵌入外连接的 WHERE 条件不是拒绝空值,但是嵌入外连接的连接条件 T2.A=T1.A AND T3.C=T1.C 是拒绝空值:

SELECT * FROM T1 LEFT JOIN
              (T2 LEFT JOIN T3 ON T3.B=T2.B)
              ON T2.A=T1.A AND T3.C=T1.C 
WHERE T3.D > 0 OR T1.D > 0

因此,查询可以转换为:

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

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:12:48  更:2022-08-19 19:16:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 11:01:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码