1

我们最近遇到了一个奇怪的 SQL Server 2008 性能问题

给定这两个查询(它们是等效的)

select max(tfiv_value) from tablefieldintvalue where tfiv_fk_tablefield = 48

select max(tfiv_value) from tablefieldintvalue where tfiv_fk_tablefield = 
(select tbfl_pk from tablefield where tbfl_name = 'Field with pk 48')

第一个大约需要 20 秒,而第二个大约需要 0 秒。

要清除子查询

(select tbfl_pk from tablefield where tbfl_name = 'Field with pk 48')

结果是48。

我们在查询计划中看到它将第二个查询转换为连接,但这仍然不能向我解释为什么会发生这种性能差异。在我看来,如果有区别的话,应该比第一个更快。

我们对所有相关领域都有一个索引。

4

1 回答 1

1

然而,我的第一个想法是,第一个查询填满了页面缓存,而第二个查询只是利用了它。缓存可以产生很大的不同。

如果两个查询的时间如此不同(并且始终如此),那么我会想象这种差异是由于表扫描与索引使用造成的。您可以通过查看查询计划来检查这一点。下一个问题是:“什么会导致这种情况?”

第一个查询通常会进行索引扫描。. . 除非有很多很多行tfiv_fk_tablefield = 48。如果它认为是这样,那么它可能会进行表扫描而不是索引扫描。也就是说,SQL Server 有一个将统计信息考虑在内的“智能”优化器。而且,当统计数据过时时,它可能会选择错误的方法。

第二个可能会强制进行索引扫描,因为它使用了一种连接类型。在这种情况下,过时的统计信息不会产生影响,并且查询会做正确的事情。

当然,这都是猜测。您应该查看查询计划,如果仍然合适,请将它们包含在此问题或其他问题中。

于 2013-07-04T19:23:45.603 回答