mysql - MySQL LEFT JOIN 与 ON 子句中的一列
问题描述
有一个需要优化的查询,查询如下所示:
SELECT *
FROM TableA
LEFT JOIN TableB ON TableA.column_1 = TableB.column_1
AND TableB.column_2 IS NOT NULL
AND TableB.column_3 IS NULL
AND TableB.column_4 IS NULL
AND TableB.column_5 IS NULL
LEFT JOIN TableC ON TableA.column_1 = TableC.column_1
AND TableC.column_3 IS NULL
AND TableC.column_4 IS NULL
AND TableC.column_5 IS NULL
查询中缓慢的部分是很多IS NULL
inON
子句。执行时间约为 4+ 秒。在使用查询一段时间后,我注意到IS NULL
可以从ON
子句中的字段中省略它。像这样:
SELECT *
FROM TableA
LEFT JOIN TableB ON TableA.column_1 = TableB.column_1
AND TableB.column_2 IS NOT NULL
AND TableB.column_3
AND TableB.column_4
AND TableB.column_5
LEFT JOIN TableC ON TableA.column_1 = TableC.column_1
AND TableC.column_3
AND TableC.column_4
AND TableC.column_5
该查询的执行时间为53ms
!,记录集也与我们从第一个查询中得到的相同。试图谷歌它并没有找到任何东西。
有谁知道它是如何工作的?
MySQL版本是5.7.25
更新
CREATE TABLE TableA (
`column_1` INT(2) NOT NULL,
`column_2` datetime NULL,
`column_3` datetime NULL,
`column_4` datetime NULL,
`column_5` datetime NULL,
)
CREATE TABLE TableB (
`column_1` INT(2) NOT NULL,
`column_2` datetime NULL,
`column_3` datetime NULL,
`column_4` datetime NULL,
`column_5` datetime NULL,
)
CREATE TABLE TableC (
`column_1` INT(2) NOT NULL,
`column_2` datetime NULL,
`column_3` datetime NULL,
`column_4` datetime NULL,
`column_5` datetime NULL,
)
INSERT INTO `TableA` (`column_1`, `column_2`, `column_3`, `column_4`, `column_5`)
VALUES
(1, '2019-08-13 00:00:00', NULL, NULL, NULL);
不包括索引,但ON
子句中使用的每个字段都有索引
解决方案
考虑下表:
create table tablename (id int, col datetime);
insert into tablename (id, col) values
(5, null),
(6, '2019-01-06 11:38:41'),
(7, '2019-01-06 11:39:40'),
(8, '2019-01-06 11:39:49');
查询:
select *
from tablename
where col
返回:
| id | col |
| --- | ------------------- |
| 6 | 2019-01-06 11:38:41 |
| 7 | 2019-01-06 11:39:40 |
| 8 | 2019-01-06 11:39:49 |
请参阅演示。
这意味着为了评估col
为0
(False) 或1
(True) 的值,由于评估发生在WHERE
子句中,MySql 将任何non null
datetime 值转换为正数>0
,评估为 True 并且任何null
值都将评估为非 True(所以视为 False) 。
你所描述的恰恰相反。
因为当评估为orTableB.column_3 IS NULL
在or子句中时返回相反的结果。TableB.column_3
>0
0
WHERE
ON
推荐阅读
- php - 我在数据表的每一列中都有复选框我想在选中复选框时停止排序
- java - 使用java interthread在控制台中传输文件
- node.js - 是否可以在一个 javascript 文件中添加来自 Node.JS 的库和来自 angular.js 以及 react.js 的一些库?
- python - 检查字符串是否是 Tkinter Text Widget 中的单词或单词的一部分
- angularjs - 带有 mvc 日期对象的日期格式不适用于 Angular JS
- cassandra - Cassandra 日志显示“Writing large partition *** to sstable”即使在删除它们之后也会发出警告
- r - 如何在没有精确光栅蒙版的情况下光栅化形状?
- android - 如果我想在一个项目的所有模块中添加相同的外部库,是否需要在所有模块中添加相同的外部库?
- javascript - 访问 id 内的标题
- domain-driven-design - 在哪里放置域模型的 HasChildren 计算属性?