我有这样的查询:
SELECT `table_1`.* from `table_1`
INNER JOIN `table_2` [...]
INNER JOIN `table_3` [...]
WHERE `table_1`.`id` IN(
SELECT `id` FROM [...]
)
AND [more conditions]
当我使用 EXPLAIN 时,末尾有'DEPENDENT SUBQUERY',但我希望在其他条件之前先执行此子查询。
有可能吗?
最佳答案
SELECT `table_1`.*
FROM `table_1`
INNER JOIN
`table_2` [...]
INNER JOIN
`table_3` [...]
WHERE `table_1`.`id` IN
(
SELECT `id`
FROM [...]
)
AND [more conditions]
如果内表被正确索引,严格意义上来说,这里的子查询根本就没有被“执行”。
由于子查询是 IN
表达式的一部分,因此条件被插入子查询并将其转换为 EXISTS
。
事实上,这个子查询在每一步都被评估:
EXISTS
(
SELECT NULL
FROM [...]
WHERE id = table1.id
)
您实际上可以在EXPLAIN EXTENDED
提供的详细说明中看到它。
这就是它被称为DEPENDENT SUBQUERY
的原因:每次求值的结果取决于table1.id
的值。子查询本身不相关,相关的是优化版本。
MySQL
总是在更简单的过滤器之后评估 EXISTS
子句(因为它们更容易评估,并且子查询有可能不会在全部)。
如果您希望子查询一次全部求值,请将查询重写为:
SELECT table_1.*
FROM (
SELECT DISTINCT id
FROM [...]
) q
JOIN table_1
ON table_1.id = q.id
JOIN table_2
ON [...]
JOIN table_3
ON [...]
WHERE [more conditions]
这会强制子查询在连接中处于领先地位,如果子查询比 table_1
小,则效率更高,如果子查询比 table_1大,则效率较低
.
如果在子查询中使用了 [...].id
上的索引,则子查询将使用 INDEX FOR GROUP-BY
执行。
关于sql - 我可以强制mysql先执行子查询吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1766702/