在SQL Server中,当使用WHERE EXISTS标准时,使用=与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
)
此问题被标记为this的重复项。这个问题是关于。存在与否。而我的问题是使用EXISTS时的re = vs IN
答案 0 :(得分:2)
没有任何区别。
写作时
WHERE A IN(B)
与写作
完全相同WHERE A = B
如果A
或B
是一列,则表达式或常量不会改变IN
运算符的性质。
如果您要写
WHERE A IN(B, C)
那与写作一样
WHERE A = B OR A = C
此条件是EXISTS
运算符内子查询的一部分的事实是不相关的。
答案 1 :(得分:1)
我认为您误解了相关子查询如何与EXISTS
一起使用。
均等比较(=
)与另一个特定值评估一个特定值,并返回true或false。除非您添加其他逻辑运算符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
运算符的上下文中使用,如果{{中至少有 1行,则将对sales.customers
的每一行进行引擎搜索。 1}}满足以下条件:
sales.orders
对于不是来自我们当前正在检查的客户的每个订单,此情况将作为WHERE o.customer_id = c.customer_id
产生。引擎将忽略这些行,因为我们正在寻找存在。仅返回false
中具有customers
且在子查询中产生一行的行。
如果我们将条件更改为customer_id
:
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
相同。引擎的行为与前面的示例相同;检查=
上是否至少有1行与orders
中的customer_id
相匹配。
因此,customers
和=
的工作方式相同。