Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在SQLServer2005中(或通常在任何RDBMS中)的IN()和EXISTS()_Sql Server_Performance - Fatal编程技术网

Sql server 在SQLServer2005中(或通常在任何RDBMS中)的IN()和EXISTS()

Sql server 在SQLServer2005中(或通常在任何RDBMS中)的IN()和EXISTS(),sql-server,performance,Sql Server,Performance,我试图找出哪个更快,一个像WHERE IN SELECT 1 FROM MyTable这样的子句,或者一个像WHERE EXISTS SELECT 1 FROM MyTable这样的子句 让我们使用SqlServer文档中的查询: SELECT * FROM Orders WHERE ShipRegion = 'WA' AND EXISTS ( SELECT EmployeeID FROM Employees AS Emp WHERE Emp.EmployeeID = Ord

我试图找出哪个更快,一个像WHERE IN SELECT 1 FROM MyTable这样的子句,或者一个像WHERE EXISTS SELECT 1 FROM MyTable这样的子句

让我们使用SqlServer文档中的查询:

SELECT * FROM Orders 
WHERE ShipRegion = 'WA' AND EXISTS (
    SELECT EmployeeID FROM Employees AS Emp 
    WHERE Emp.EmployeeID = Orders.EmployeeID)

如果有人知道答案,我很想知道,但我真的很想知道如何在SQLServer2005中为自己测试它。我是SqlServer的noob

谢谢

您还可以在以下情况下删除WHERE子句:


查询优化器应该能够为两个查询生成相同的执行计划。我会选择一个更可读的。

要亲自查看,您可以: 比较实际执行成本,运行

SET STATISTICS IO ON
SET STATISTICS TIME ON
然后运行两个查询


同时比较执行计划,突出显示两个查询并按Ctrl+L,您将看到计划。您很可能会看到完全相同的计划。

sql子查询虽然完全相同,但不会给出您要查找的答案,因为它是相关的,可以更改为联接

一般来说,EXISTS应该更快,因为它给出了一个结果,一旦找到第一行,就不必再找到任何关系,而In仍然必须找到 后续行,直到完成为止

所以

SELECT * FROM Orders 
WHERE ShipRegion = 'WA' AND EXISTS (
    SELECT 'x' FROM Employees AS Emp 
    WHERE Emp.EmployeeID = 42)
应该在之前完成

SELECT * FROM Order
WHERE ShipRegion = 'WA' AND EmployeeID IN (
    SELECT EmployeeID FROM Employees AS Emp 
    WHERE Emp.EmployeeID = 42)

使用内部联接比使用子查询更快:

SELECT * 
  FROM Order o
 INNER JOIN Employees e ON o.EmployeeID = e.EmployeeID
 WHERE ShipRegion = 'WA'
或符合特定标准:

 SELECT * 
  FROM Order o
 INNER JOIN Employees e ON o.EmployeeID = e.EmployeeID
 WHERE ShipRegion = 'WA'
   AND e.EmployeeID = 42

事实上,也许这不是一个好例子。从订单到员工的外键约束将消除测试的需要。嗯。。。我想这要追溯到它在找到第一个匹配项时是否停止。如果是的话,那就说明我的两个例子之间没有区别。如果没有,那么即使没有where子句,EXISTS也会更快,不是吗?谢谢你的回复。为什么不在第一场比赛后停止呢?从理论上讲,一个好的查询优化器应该高效地执行所有这些操作。实际上,一些数据库引擎可能更擅长优化一个变量。好的方面是,他的查询并不相同,所以任何关于哪一个更有效的讨论都是比较苹果和梨。虽然我认为结果在逻辑上应该是等价的,但我并不期望优化器能够很好地消除这些不必要的条件,因为它们应该非常罕见。在找到匹配项后,是否需要继续?显然不在需要,但为什么在?谢谢你的分析!这是我寻找的大部分,特别是理论或技术部分,在第一次击中后停止。你可能会认为MSDN在线图书会提到这一点。哦,我的例子不一定很好。我脑子里想不出什么现实的东西,所以我只是抄袭了MS的示例代码来寻找存在。纠正约翰,我的错误。因为我们可以将子句缩减为AND Orders.EmployeeID=42,所以我们最多只能看到基于主键的一行。如果子条款改为“Emp”,其中Emp.Name='Smith',我的答案更有意义。不,这个答案是错误的。1当您说IN仍然必须查找后续行…,您假设数据库将执行循环半联接,但对于性能重要的大型表,它可能会改为哈希联接。2如果查询作为循环联接执行,IN和EXISTs都可能在找到的第一行停止,并且IN谓词可以保证永远不为null,否则语义不同。谢谢!这是我想问的问题的另一部分。我知道一定有办法测量这些东西,但我不知道怎么测量。现在我知道了!
SELECT * 
  FROM Order o
 INNER JOIN Employees e ON o.EmployeeID = e.EmployeeID
 WHERE ShipRegion = 'WA'
 SELECT * 
  FROM Order o
 INNER JOIN Employees e ON o.EmployeeID = e.EmployeeID
 WHERE ShipRegion = 'WA'
   AND e.EmployeeID = 42