使用' max'进行查询的奇怪表现

时间:2013-07-04 18:46:59

标签: sql-server

我们最近遇到了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。

我们在查询计划中看到它将第二个查询转换为连接,但这仍然没有向我解释为什么会出现这种性能差异。在我看来,如果存在差异,那么第一个应该更快。

我们在所有相关领域都有索引。

1 个答案:

答案 0 :(得分:1)

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

如果两个查询的时间如此不同(并且始终如此),那么我会想到差异是由于表扫描与索引使用有关。您可以通过查看查询计划来查看此信息。接下来的问题是:“会导致什么?”

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

第二种可能会强制进行索引扫描,因为它使用的是一种连接方式。在这种情况下,过时的统计数据不会产生影响,而查询也是正确的。

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