存在/不存在:'选择1' vs'选择字段'

时间:2014-10-20 08:59:07

标签: sql sql-server oracle exists

两者中的哪一个会表现得更好(我最近被指责不小心我的代码,因为我在Oracle中使用了后者):

Select * 
from Tab1
Where (not) exists(Select 1 From Tab2 Where Tab1.id = Tab2.id)


Select * 
from Tab1
Where (not) exists(Select Field1 From Tab2 Where Tab1.id = Tab2.id)

或两者都相同?

请从SQL Server透视图和Oracle透视图中回答。

我用google搜索(主要来自sql-server方面)并发现对此仍存在很多争论,尽管我目前的观点/假设是两个RDMBS中的优化者已经足够成熟,可以理解所有需要子查询是一个布尔值。

4 个答案:

答案 0 :(得分:16)

是的,它们是一样的。 exists检查子查询中是否至少有一行。如果是,则评估为true。子查询中的列无论如何都不重要。

根据MSDNexists

  

指定要测试行是否存在的子查询。

Oracle

  

EXISTS条件测试子查询中是否存在行。

也许MySQL documentation更能解释:

  

传统上,EXISTS子查询以SELECT *开头,但它可以从SELECT 5或SELECT column1开始,或者任何东西。 MySQL忽略了这样一个子查询中的SELECT列表,所以没有区别。

答案 1 :(得分:5)

我知道这已经过时了,但我想补充几点我最近观察到的......

即使存在只检查存在,当我们写“select *”all时,列将被扩展,除了这个轻微的开销之外,没有差异。

来源:
http://www.sqlskills.com/blogs/conor/exists-subqueries-select-1-vs-select/

<强>更新
我引用的文章似乎无效。即使我们编写select 1时,SQLServer也会扩展所有列。

使用各种方法时,请参阅以下链接进行深入分析和性能统计。

Subquery using Exists 1 or Exists *

答案 2 :(得分:3)

子查询列列表中的表达式完全无关紧要,它甚至不会被执行:

select * from dual t1
where exists (
    select 1/0 from dual t2
         --^^^ division by 0  
    where t2.dummy = t2.dummy)
/

DUMMY
--------
X

答案 3 :(得分:1)

在我使用之间的经验中唯一需要注意的事情 "EXISTS(SELECT * ..." 和 "EXISTS(SELECT 1 ..." 是模式绑定对象中不允许使用 "*" -- 它会抛出:

模式绑定对象中不允许使用语法“*”。