5

我有一个双重自联接查询,其中在交换搜索值时性能会严重下降。

-- 500,000 i/o & 500ms execution
select
  fooA.ID
  , fooB.ID
from
  foo AS fooA
  INNER JOIN bar AS barA ON fooA.barID = barA.barID
  INNER JOIN foo AS fooB ON fooA.fooID = fooB.fooID -- self join
  INNER JOIN bar AS barB ON fooB.barID = barB.barID
where
  barA.value = 'xyz'
  AND barB.value = '60'

-- 5,000 i/o & 5ms execution
select
  fooA.ID
  , fooB.ID
from
  foo AS fooA
  INNER JOIN bar AS barA ON fooA.barID = barA.barID
  INNER JOIN foo AS fooB ON fooA.fooID = fooB.fooID -- self join
  INNER JOIN bar AS barB ON fooB.barID = barB.barID
where
  barA.value = '60'
  AND barB.value = 'xyz'
  • 值“xyz”在“bar”表中列出了 150,000 次。
  • 值“60”在“bar”表中列出了 500 次。
  • 查询计划是相同的,只是最里面的循环返回 150,000 行或 500 行,具体取决于首先列出的搜索值。
  • 搜索对非聚集索引执行搜索。
  • 使用 FULLSCAN 更新了两个表的统计信息。

为什么 SQL 查询优化器不能正确识别在这两种情况下查询计划的最内连接应该是行数最少的连接?

4

1 回答 1

3

SQL Server 不会在每次执行查询时重新编译它。它只执行一次,并针对第一次看到的确切值进行了优化。我猜你缓存了一个不幸的计划。

尝试OPTION (RECOMPILE)在最后添加。

于 2012-05-15T18:46:34.150 回答