我们有TABLE A按日期进行分区,并且不包含今天的数据,它只包含前一天的数据,并且还包含年初至今的数据。SQL Server 2005查询计划优化器在日期分区表上窒息
我们已经将表B按照包含今天的数据以及从前一天到今年的数据进行分区。上表B的顶部有它连接针对View_C
,View_D
和左外联接表E. View_C
和View_D
从1个表中的每个选择和不具有任何其它表连接在一个视图,View_B
所以View_B
看起来像
SELECT b.Foo, c.cItem, d.dItem, E.eItem
FROM TABLE_B b JOIN View_C c on c.cItem = b.cItem
JOIN View_D d on b.dItem = d.dItem
LEFT OUTER JOIN TABLE_E on b.eItem = e.eItem
View_AB
在提取日期以及另一个约束条件下加入表A和View_B
。所以它看起来是这样的:
SELECT a.Col_1, b.Col_2, ...
FROM TABLE_A a LEFT OUTER JOIN View_B b
on a.ExtractDate = b.ExtractDate and a.Foo=b.Foo
-- no where clause
当从超过前一天的任何其他数据搜索,查询分析器做什么预期和做了哈希匹配连接,完成外连接,并读取约116页价值来自表B的数据。然而,如果在前一天运行,查询优化器会吓倒并使用嵌套连接,扫描表7000次以上并在连接中读取8,000,000多页。
我们可以通过使用联接提示来伪造/强制它使用不同的查询计划,但是会导致视图中的任何约束都会导致优化器抛出查询无法处理的错误由于加入提示而完成。
编辑以添加pages/scans =与先前运行优化程序正确选择散列而不是嵌套连接的前一天运行的扫描相同的编号。
正如评论所说,我们严厉通过创建TABLE_B
覆盖索引覆盖在View_B
的加入降低了冲击,但IO仍然高于这将是,如果优化器选择正确的计划,特别是因为除了前几天的搜索之外,该指数基本上是多余的。
该sqlplan是在http://pastebin.com/m53789da9,抱歉,它不是格式很好的版本。
任何机会,你可以发布每个.sqlplan,所以我们可以看到差异? – chadhoc 2009-11-17 14:34:25
是由ExtractDate聚集的两个表吗? ExtractDate上的非覆盖非聚集索引也可能导致此行为(即使使用分区)。 – 2009-11-17 16:08:20
这些表也由ExtractDate聚类,A和B之间的连接标准应该由表上的索引覆盖。我们通过在连接标准上创建一个覆盖索引来缓解了这个问题。在最佳连接中,它仍然会执行更多的页面读取操作,但这是可以接受的。 – Rebthor 2009-11-18 14:44:16