2010-01-27 50 views
3

我听说使用IN子句会伤害性能,因为它没有正确使用索引。请参阅下面的示例:是否使用WHERE 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?如果是的话哪些受到影响?

+2

类似http://stackoverflow.com/questions/761150/how-does-the-in-predicate-work-in-sql – 2010-01-27 20:59:14

回答

5

Yes, assuming relatively large data sets.

它被认为更好地使用EXISTS大型数据集。我遵循这一点,并注意到我的代码执行时间有所改进。

根据文章,它与INEXISTS是如何内部化有关。另一篇文章:http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

+2

存在使用JOIN运算符,其中IN使用OR运算符。 – mrdenny 2010-01-27 21:47:44

+0

这个答案根本不对。第一个链接意味着给定查询的查询计划仅依赖于查询 - 至少在涉及'in'和'exists'查询时。这完全是不真实的;像“统计”和“参数嗅探”这样的东西的存在应该足以看出这个想法与现实不符。第二篇文章很好,但它完全不相关 - 它根本不是在谈论性能,而是在讨论'not in'中含有空集的混淆语义。 – 2015-01-11 14:42:14

+0

为了澄清:肯定会有一些情况,“IN”条款不是最理想的,但这不是一般趋势;并且它没有正确使用索引的概念不会由此答案所说或所链接的任何内容来支持。 – 2015-01-11 17:23:37

0

超过INTable Variable,我认为正确使用索引会提高查询性能。

此外,从表名​​看来,它似乎并不像你会有很多条目,所以在这个特定的例子中,你走哪条路可能是没有意义的。

其次,IN将仅被评估一次,因为没有子查询。在你的情况下,@ IDList变量可能会导致你需要的错配匹配@IDList1, @IDList2, @IdList3....,因为IN需要一个列表。

作为一般的经验法则,您应该避免使用IN进行子查询,并使用EXISTS进行加入 - 您会获得更好的性能。

0

IN会伤害性能,因为SQL Server必须生成一个完整的结果集,然后根据结果集中的行数创建一个巨大的IF语句。顺便说一句,调用UDF也可能是一个真正的性能问题。他们非常好用,但如果你不小心,可以真正影响性能。您可以通过Google UDF和Performance对此进行一些研究。

0

您的第一个示例与第二个示例不同,因为WHERE X IN (@variable)WHERE X = @variable相同(即您不能具有变量列表)。

关于性能,您必须查看执行计划以查看选择了哪些索引。

+0

我看着我的原始查询,并想我明白你在说什么。看看我的更新 – 2010-01-27 21:44:24

+0

@AbeMiessler你的版本之间仍然存在语义上的差异。如果列表中有重复项,则会在第二个项中导致交叉连接效果。所以这在理论上应该对执行计划有一个小的影响,但如果列表很小(第一个案例计划可能与第二个案例计划可能与第二个案例计划相同,以获得不同的列表),则可能并不重要。我的钱将近乎类似的执行计划。 – 2010-01-28 14:42:59

2

找到它非常简单 - 打开Management Studio,将两个版本的查询放入,然后在打开显示执行计划的情况下运行。比较两个执行计划。通常(但并非总是),查询优化器会为逻辑上等效的查询的不同版本制定相同的确切计划/从字面上做相同的事情。实际上,这就是它的目的 - 目标是优化器将采用任何版本的查询,假设逻辑相同,并制定最佳计划。 唉,这个过程并不完美。

这里有一个科学的比较:

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/

相关问题