首页 > 解决方案 > 具有多个子查询连接的 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 JOINto的更改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. 

我不确定为什么两个计划在这两种情况下不同,以及这如何导致执行时间不同。

谁能帮我解释一下实际的执行顺序可能是什么?

标签: mysqlsql

解决方案


连接顺序取决于查询计划器在它认为合适的情况下进行优化。有时它会出错。如果您认为连接顺序不是最理想的,您可以通过指定SELECT STRAIGHT_JOIN而不是来强制它SELECT。这将强制查询计划器按照查询中列出的顺序连接表。

外连接总是会变慢,因为它们必须扫描更多的行——它们不能丢弃两边都不匹配的行。


推荐阅读