Sql 存在/不存在:“选择1”与“选择字段”
这两个选项中哪一个执行得更好?我最近被指控对我的代码不小心,因为我在Oracle中使用了后者: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的
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:非常感谢,我很久以前就读过你的答案,但是有些人错过了几件事。再次感谢你揭穿了这个神话