条件子查询是否已优化,如果条件为假?

时间:2010-05-20 14:48:25

标签: sql mysql performance oracle subquery

我有一个表格foo和一个表格栏,其中每个foo可能有一个条形图(并且一个条形图可能属于多个foos)。

现在我需要用酒吧选择所有的泡沫。我的sql看起来像这样

SELECT * 
  FROM foo f 
 WHERE [...] 
   AND ($param IS NULL OR (SELECT ((COUNT(*))>0) 
                             FROM bar b 
                            WHERE f.bar = b.id))

在运行时替换$ param。

问题是:即使param为null,子查询是否会被执行,或者dbms会优化子查询吗?

我们正在使用mysql,mssql和oracle。这些与上述有什么区别?

2 个答案:

答案 0 :(得分:2)

这取决于。如果每次都将该查询传递给DBMS,那么编译器应该意识到它不需要调用子查询。如果它是静态过程,那么它取决于编译器如何存储执行计划。如果它在第一次调用过程时存储执行计划,并且第一次调用它时$ param不为null,那么它可能实际上在每次运行过程时调用子查询。

另一方面,对于此类检查,您应该考虑存在而不是计数(*)

Select ..
From foo f
Where ....
    And ( $param Is Null
            Or Exists   (
                        Select 1
                        From bar b
                        Where b.id = f.bar
                        ))

答案 1 :(得分:1)

在这种情况下,我建议您自己在应用程序代码中进行优化,而不是依赖来自3个不同RDBMS的优化器来始终如一地处理它。

如果$ param为null,只需从foo表中选择。 如果没有,请加入吧台。

伪码:

if ($param is null)
  SELECT * 
  FROM foo f 
  WHERE [...] 
else
  SELECT distinct f.* 
  FROM foo f 
  inner join bar b on f.bar = b.id
  WHERE [...] 
end if