使用具有 EXISTS 条件的 = 与 IN 运算符的性能差异是什么?



在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

如果AB是列,则表达式或常量不会更改IN运算符的性质。

如果你在哪里写

WHERE A IN(B, C)

这和写作一样

WHERE A = B OR A = C

此条件是EXISTS运算符内子查询的一部分这一事实无关紧要。

我认为您误解了相关子查询如何与EXISTS一起工作。

相等比较(=)评估一个特定的值另一个特定的值,并返回真或假。它无法计算多个值,除非您添加其他逻辑运算符AND/ORIN运算符只是使用=运算符简化一堆OR的一种方式,因此更容易阅读,正如 Zohar 在另一个答案中所解释的那样。

另一方面,EXISTS运算符使用左半连接来检查特定记录是否存在。EXISTS在布尔上下文中使用,只要您想检查特定行是否存在。SQL 引擎在找到第一个行后立即停止搜索匹配的行。这是左半连接的用途,也是与左外连接的区别之一(除了检索连接表的数据和匹配行量)。

所以当你写:

FROM
sales.customers c
WHERE
EXISTS (
SELECT *
FROM sales.orders o
WHERE o.customer_id = c.customer_id
)

您正在使用相关的子查询,将customersorders链接。子查询用于EXISTS运算符的上下文中,这将使引擎搜索,对于sales.customers的每一行,如果sales.orders至少有1 行满足此条件:

WHERE o.customer_id = c.customer_id

对于不是来自我们当前正在检查的客户的每个订单,此情况将导致false。引擎将忽略这些行,因为我们正在寻找存在。将仅返回具有在子查询中生成行的customer_idcustomers中的行。

如果我们将条件更改为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的工作方式相同。

最新更新