如果在SELECT和WHERE子句中都使用子查询,它是否被执行多次?

时间:2015-04-07 21:51:55

标签: mysql

e.g。如果我写

SELECT (subquery) FROM table WHERE (subquery)

每行会(subquery)执行多次?

我在SELECT中对它进行别名并在WHERE中使用它,但这似乎没有效果。

2 个答案:

答案 0 :(得分:1)

让我们看一下用于说明此用例的非常简单的查询的EXPLAIN PLAN

EXPLAIN 
SELECT (SELECT 1 FROM YOURTABLE LIMIT 1) 
 FROM DUAL 
 WHERE (SELECT 1 FROM YOURTABLE LIMIT 1);

忽略LIMIT 1,它们只是为了避免我的测试表上出现多行错误。

结果集将是

'1', 'PRIMARY', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'No tables used'
'3', 'SUBQUERY', 'YOURTABLE', 'index', NULL, 'PRIMARY', '4', NULL, '6', 'Using index'
'2', 'SUBQUERY', 'YOURTABLE', 'index', NULL, 'PRIMARY', '4', NULL, '6', 'Using index'

正如您所看到的,是的,子查询将被执行两次。

如果要在多个地方使用子查询的值,则可以考虑使用JOIN代替。

答案 1 :(得分:1)

一般来说,答案是"是"。虽然查询优化器有权消除这种常见的子表达式,但查询优化器很少这样做。

如果将子查询放在from子句中,则只应执行一次:

SELECT s.value
FROM table cross join
     (subquery) s
WHERE s.value

或者,如果您使用子查询:

SELECT value
FROM (SELECT (subquery) as value
      FROM table
     ) s
WHERE value <> 0;

在MySQL中,后一种结构强加了实现子查询的成本。因此,还有另一个MySQL扩展可能会使这更有效:

SELECT (subquery) as value
FROM table 
HAVING value <> 0;