我听说使用IN子句会影响性能,因为它没有正确使用索引。见下面的例子:
SELECT ID, Name, Address
FROM people
WHERE id IN (SELECT ParsedValue FROM UDF_ParseListToTable(@IDList))
使用下面的表格获得这些结果会更好吗?
SELECT ID,Name,Address
FROM People as p
INNER JOIN UDF_ParseListToTable(@IDList) as ids
ON p.ID = ids.ParsedValue
这取决于您使用的SQL Server版本吗?如果是的话哪些受到影响?
答案 0 :(得分:5)
Yes, assuming relatively large data sets.
将EXISTS
用于大型数据集会更好。我遵循这一点并注意到代码执行时间的改进。
根据文章,它与IN
与EXISTS
内化的方式有关。另一篇文章:http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx
答案 1 :(得分:2)
很容易找到 - 打开管理工作室,将两个版本的查询放入,然后在启用Show Execution计划的情况下运行。比较两个执行计划。通常,但并非总是如此,查询优化器将对逻辑上等效的查询的不同版本做出相同的确切计划/字面上做同样的事情。
实际上,这就是它的目的 - 目标是优化器将采用任何版本的查询,假设逻辑相同,并制定最佳计划。 唉,这个过程并不完美。
这是一个科学比较:
http://sqlinthewild.co.za/index.php/2010/01/12/in-vs-inner-join/ http://sqlinthewild.co.za/index.php/2009/08/17/exists-vs-in/
答案 2 :(得分:0)
超过IN
或Table Variable
,我认为正确使用索引会提高查询效果。
另外,从表名来看,似乎你不会在其中包含大量条目,因此在这个特定的例子中,你走哪条路可能没有实际意义。
其次,IN
只会被评估一次,因为没有子查询。在您的情况下,@ IDList变量可能会导致您需要@IDList1, @IDList2, @IdList3....
的错误匹配,因为IN
需要列表。
作为一般经验法则,您应该避免IN
使用子查询并使用EXISTS
加入 - 您将获得更好的效果。
答案 3 :(得分:0)
IN会损害性能,因为SQL Server必须生成完整的结果集,然后根据结果集中的行数创建可能的巨大IF语句。顺便说一下,调用UDF也可能是一个真正的性能打击。如果你不小心的话,它们非常好用但可以真正影响性能。您可以使用Google UDF和Performance对此进行一些研究。
答案 4 :(得分:0)
您的第一个示例与第二个示例不同,因为WHERE X IN (@variable)
与WHERE X = @variable
相同(即您不能拥有变量列表)。
关于性能,您必须查看执行计划以查看选择了哪些索引。