Sql 存在/不存在:“选择1”与“选择字段”

Sql 存在/不存在:“选择1”与“选择字段”,sql,sql-server,oracle,exists,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的

这两个选项中哪一个执行得更好?我最近被指控对我的代码不小心,因为我在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的角度回答

我主要从sql server方面搜索,发现关于这一点仍有很多争论,尽管我目前的观点/假设是,两个RDMB中的乐观者都足够成熟,能够理解子查询所需的全部内容都是布尔值。

是的,它们是相同的。exists检查子查询中是否至少有一行。如果是,则其计算结果为true。子查询中的列在任何方面都不重要

根据,存在:

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

以及:

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

也许这更能说明问题:

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


我知道这是老生常谈,但我想补充一下我最近观察到的几点

即使exists只检查是否存在,但当我们编写select*all时,列将被展开,除了这一微小的开销之外,没有区别

资料来源:

更新: 我提到的文章似乎无效。即使在编写时,选择1,SQLServer将展开所有列

使用各种方法时,请参阅下面的链接以获得深入分析和性能统计信息


根据我的经验,在使用 退出选择*。。。并退出选择1。。。在架构绑定对象中不允许使用*-它将抛出:


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

子查询列列表中的表达式完全不重要,甚至不会执行:

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

DUMMY
--------
X

没有区别,它们都是一样的。检查两个查询的执行计划以进行验证。看看这个答案。它对Postgres有影响吗?我不知道。我没有使用Postgres的经验。PostgreSQL也是一样。你也可以选择空值,因为Conor的文章实际上是错误的。他建议SELECT*将扩展所有列元数据,而SELECT 1不会。但事实上,他们都是这样做的。您可以通过拒绝对列的权限并运行SELECT 1(如果存在)从T中选择1来看到这一点;如果列“Foo”上的SELECT权限被拒绝,或者通过简单地计时添加更多列的效果,或者查看调试器,则可能会意外失败@MartinSmith:非常感谢,我很久以前就读过你的答案,但是有些人错过了几件事。再次感谢你揭穿了这个神话