mysql - 具有多个子查询连接的 MySQL 查询中的执行顺序
问题描述
我有以下查询,LEFT JOIN
前两个子查询e
和之间有a
一个INNER JOIN
,最后两个子查询a
和之间有一个m
:
SELECT {cols}
FROM
(SELECT {cols}
FROM {table}
WHERE {conditions}) AS e
LEFT JOIN
(SELECT {cols}
FROM {table}
WHERE {conditions}) AS a
ON e.col = a.col
INNER JOIN
(SELECT {cols}
FROM {table}
WHERE {conditions}) AS m
ON e.col = m.col
当我将第二个连接从 更改INNER JOIN
为 时LEFT JOIN
,执行时间增加了~200
. 每个子查询的记录数如下:
e -> Number of records: 303
a -> Number of records: 18
m -> Number of recordings: 295
我假设 MySQL 会将每个子查询评估为一个独立的子查询,然后进行连接,在这种情况下,鉴于如上所示的相对较少的记录数,从INNER JOIN
to的更改LEFT JOIN
不应该导致执行时间的增加。
所以,显然这似乎不是遵循的执行顺序。
解释计划:
Case 1 with INNER JOIN: join e with m first, then join with a.
Case 2 with LEFT JOIN: join e with a first, then join with m.
我不确定为什么两个计划在这两种情况下不同,以及这如何导致执行时间不同。
谁能帮我解释一下实际的执行顺序可能是什么?
解决方案
连接顺序取决于查询计划器在它认为合适的情况下进行优化。有时它会出错。如果您认为连接顺序不是最理想的,您可以通过指定SELECT STRAIGHT_JOIN
而不是来强制它SELECT
。这将强制查询计划器按照查询中列出的顺序连接表。
外连接总是会变慢,因为它们必须扫描更多的行——它们不能丢弃两边都不匹配的行。
推荐阅读
- spring-boot - 登录后被重定向,但我实际上并没有登录 Spring Security
- excel - VBA If-ElseIf 语句不返回正确的结果
- windows - 有没有办法让批处理文件自动填充/自动填充文件路径到另一个通过批处理文件打开的应用程序中?
- aurelia - 如何将 Aurelia 项目从 v0.24.0 版本升级到当前版本 v1.2.3
- active-directory - 通过 terraform 将 EC2 实例加入 AD 域
- python - Python在具有未定义整数和浮点数的列表和元素列表中查找最大值
- swi-prolog - 可靠地找到 quasi_quotations 实现
- java - 嵌套 for 循环中的逻辑问题
- kubernetes - 是否可以使用 Terraform 编辑现有的 Kubernetes 资源?
- javascript - 将值从 razor 视图提交到通过 HTTP Post 方法接受值的控制器操作