在SQL服务器中,当使用WHERE EXIST标准时,使用=与IN运算符有什么性能差异吗?
例:
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers c
WHERE
EXISTS (
SELECT *
FROM sales.orders o
WHERE customer_id = c.customer_id --we can also replace = with IN - for example customer_id IN c.customer_id or say c.customer_id IN customer_id
)
另一个例子是:
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers c
WHERE
EXISTS (
SELECT *
FROM #Customers x --say #Customers is temp table containing a couple of customers for which we want to show the output
WHERE c.customer_id = x.customer_id --we can also replace = with IN - for example c.customer_id IN x.customer_id or say x.customer_id IN c.customer_id
)
此问题标记为重复。这个问题是重新的。存在与在。而我的问题是使用 EXISTS 时 re = vs IN
没有任何区别。
当你在写作时
WHERE A IN(B)
和写作一模一样
WHERE A = B
如果A
或B
是列,则表达式或常量不会更改IN
运算符的性质。
如果你在哪里写
WHERE A IN(B, C)
这和写作一样
WHERE A = B OR A = C
此条件是EXISTS
运算符内子查询的一部分这一事实无关紧要。
我认为您误解了相关子查询如何与EXISTS
一起工作。
相等比较(=
)评估一个特定的值和另一个特定的值,并返回真或假。它无法计算多个值,除非您添加其他逻辑运算符AND
/OR
。IN
运算符只是使用=
运算符简化一堆OR
的一种方式,因此更容易阅读,正如 Zohar 在另一个答案中所解释的那样。
另一方面,EXISTS
运算符使用左半连接来检查特定记录是否存在。EXISTS
在布尔上下文中使用,只要您想检查特定行是否存在。SQL 引擎在找到第一个行后立即停止搜索匹配的行。这是左半连接的用途,也是与左外连接的区别之一(除了检索连接表的数据和匹配行量)。
所以当你写:
FROM
sales.customers c
WHERE
EXISTS (
SELECT *
FROM sales.orders o
WHERE o.customer_id = c.customer_id
)
您正在使用相关的子查询,将customers
与orders
链接。子查询用于EXISTS
运算符的上下文中,这将使引擎搜索,对于sales.customers
的每一行,如果sales.orders
中至少有1 行满足此条件:
WHERE o.customer_id = c.customer_id
对于不是来自我们当前正在检查的客户的每个订单,此情况将导致false
。引擎将忽略这些行,因为我们正在寻找存在。将仅返回具有在子查询中生成行的customer_id
的customers
中的行。
如果我们将条件更改为IN
:
FROM
sales.customers c
WHERE
EXISTS (
SELECT *
FROM sales.orders o
WHERE o.customer_id IN (c.customer_id)
)
子查询将检查满足以下条件的表sales.orders
上是否存在:
WHERE o.customer_id IN (c.customer_id)
这恰好与我们在=
示例中引用的c.customer_id
相同。引擎的行为将与前面的示例相同;检查orders
上是否至少有 1 行与customers
中的customer_id
匹配。
因此,=
和IN
的工作方式相同。