实践"存在(从...中选择1)"来自何处?

Vil*_*lx- 19 sql history

绝大多数人支持我自己的看法,有下面的语句没有区别:

SELECT * FROM tableA WHERE EXISTS (SELECT * FROM tableB WHERE tableA.x = tableB.y)
SELECT * FROM tableA WHERE EXISTS (SELECT y FROM tableB WHERE tableA.x = tableB.y)
SELECT * FROM tableA WHERE EXISTS (SELECT 1 FROM tableB WHERE tableA.x = tableB.y)
SELECT * FROM tableA WHERE EXISTS (SELECT NULL FROM tableB WHERE tableA.x = tableB.y)
Run Code Online (Sandbox Code Playgroud)

然而今天,在我们的内部开发人员会议中,我提出了与之相反的主张,select 1即提出的方法是select *选择所有(不必要的)数据,从而损害性能.

我似乎记得有一些旧版本的Oracle或其他地方都是如此,但我找不到对它的引用.所以,我很好奇 - 这种做法如何诞生的?这个神话来自哪里?

补充:由于有些人坚持认为这确实是一种错误的信念,这里是一个谷歌查询,显示很多人这样说.如果你太懒,请查看这个直接链接,其中一个人甚至比较执行计划,发现它们是等效的.

cod*_*ike 23

你问题的主要部分是 - "这个神话来自哪里?"

所以回答这个问题,我想人们用sql学习的第一个性能提示select *是在大多数情况下效率低下.因此,在这种特定情况下效率高的事实在某种程度上是违反直觉的.所以人们对它持怀疑态度并不奇怪.但是一些简单的研究或实验应该足以消除大多数神话.虽然人类历史有点表明神话很难被驱逐.

  • 我是第一个注意到我真正问题的人!还有一个看似合理的解释! (4认同)

gbn*_*gbn 13

作为演示,试试这些

SELECT * FROM tableA WHERE EXISTS (SELECT 1/0 FROM tableB WHERE tableA.x = tableB.y)
SELECT * FROM tableA WHERE EXISTS (SELECT CAST('bollocks' as int) FROM tableB WHERE tableA.x = tableB.y)
Run Code Online (Sandbox Code Playgroud)

现在阅读ANSI标准.ANSI-92,第191页,案例3a

If the <select list> "*" is simply contained in a <subquery>
          that is immediately contained in an <exists predicate>, then
          the <select list> is equivalent to a <value expression> that
          is an arbitrary <literal>.
Run Code Online (Sandbox Code Playgroud)

最后,大多数RDBMS上的行为应该忽略EXISTS子句中的THE*.根据昨天的这个问题(Sql Server 2005 - 如果不存在则插入)这对SQL Server 2000不起作用,但我知道它在SQL Server 2005+上有效