我们最近遇到了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。
我们在查询计划中看到它将第二个查询转换为连接,但这仍然没有向我解释为什么会出现这种性能差异。在我看来,如果存在差异,那么第一个应该更快。
我们在所有相关领域都有索引。
答案 0 :(得分:1)
然而,我首先想到的是,第一个查询填充了页面缓存,第二个查询只是利用了它。缓存可以产生很大的不同。
如果两个查询的时间如此不同(并且始终如此),那么我会想到差异是由于表扫描与索引使用有关。您可以通过查看查询计划来查看此信息。接下来的问题是:“会导致什么?”
第一个查询通常会进行索引扫描。 。 。除非有很多很多行tfiv_fk_tablefield = 48
。如果它这样认为,那么它可能会进行表扫描而不是索引扫描。也就是说,SQL Server有一个“智能”优化器,可以将统计信息考虑在内。并且,当统计数据过时时,它可能会选择错误的方法。
第二种可能会强制进行索引扫描,因为它使用的是一种连接方式。在这种情况下,过时的统计数据不会产生影响,而查询也是正确的。
当然,这都是猜测。您应该查看查询计划,如果仍然适当,请将其包含在此问题或其他问题中。