快速说明:我们内部运行SQL Server 2012,但问题似乎也发生在2008和2008 R2,也可能是旧版本。
我一直在调查我们的一些代码中的性能问题,并且我已经将问题跟踪到以下非常简单的查询:
SELECT min(document_id)
FROM document
WHERE document_id IN
(SELECT TOP 5000 document_id FROM document WHERE document_id > 442684)
我注意到这个查询需要花费很长的时间(在18到70秒之间,具体取决于运行它的机器的资源),当最终值(大于)之后大约为442000或更大时返回。在此之下,查询几乎立即返回。
我将查询调整为如此:
SELECT min(t.document_id)
FROM (SELECT TOP 5000 document_id FROM document WHERE document_id > 442684) t
立即返回>的所有值。我曾经测试过。
我已经解决了手头的性能问题,所以我很高兴,但我仍然对为什么原始查询在442000上执行得如此糟糕以及为什么它几乎可以快速运行而感到困惑价值低于(400000,350000等)。
任何人都能解释一下吗?
编辑:修正第二个查询为min而不是max(这是一个错字)
答案 0 :(得分:3)
评论太长了。
了解SQL Server(和其他数据库)中的性能的秘诀是执行计划。您需要查看查询的执行计划,以了解正在发生的事情。
您的查询的第一个版本具有连接操作。带有子查询的IN
是表达JOIN
的另一种方式。 SQL Server有几种实现连接的方法,例如散列匹配,合并排序,嵌套循环和索引查找操作。优化器选择它认为最好的那个。
在没有看到执行计划的情况下,我最好的猜测是优化器改变了对in
使用的最佳算法的看法。根据我的经验,这通常意味着它从更合理的算法切换到嵌套循环算法。
答案 1 :(得分:0)
将您的查询更改为
从文档中选择min(document_id),其中document_id> 442684
select in(select top 5000)在sql中是一个坏主意 - 如果测试它可以扩展到5000。不知道为什么优化器在max()情况下运行良好