2009-11-17 94 views
1

我们有TABLE A按日期进行分区,并且不包含今天的数据,它只包含前一天的数据,并且还包含年初至今的数据。SQL Server 2005查询计划优化器在日期分区表上窒息

我们已经将表B按照包含今天的数据以及从前一天到今年的数据进行分区。上表B的顶部有它连接针对View_CView_D和左外联接表E. View_CView_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,抱歉,它不是格式很好的版本。

+0

任何机会,你可以发布每个.sqlplan,所以我们可以看到差异? – chadhoc 2009-11-17 14:34:25

+0

是由ExtractDate聚集的两个表吗? ExtractDate上的非覆盖非聚集索引也可能导致此行为(即使使用分区)。 – 2009-11-17 16:08:20

+0

这些表也由ExtractDate聚类,A和B之间的连接标准应该由表上的索引覆盖。我们通过在连接标准上创建一个覆盖索引来缓解了这个问题。在最佳连接中,它仍然会执行更多的页面读取操作,但这是可以接受的。 – Rebthor 2009-11-18 14:44:16

回答

1

如果你能张贴每个查询的.sqlplan这将有助于确定,但我的预感是,你之前的当天日期查询时,并嵌套循环是可能得到一个并行计划对表中包含的分区进行常量循环,然后为每个分区产生一个工作线程(有关此的更多信息,请参阅SQLCAT post on parallel plans with partitioned tables in Sql2005)。但是,如果没有看到计划,则无法验证是否是这种情况。

+0

SQL 2k8 QO在分区方面的表现要好得多 – 2009-11-17 16:06:48

+1

是的,虽然给予标题我假设2005 ... – chadhoc 2009-11-17 16:25:48

+0

我不认为这是什么原因造成这里的问题,虽然这是一个非常有趣的阅读。使用OPTION(MAXDOP 1)运行仍然使查询优化器在数百万页IO中徘徊。 看起来,优化器正在部分地被绑定到nesteed视图上。 – Rebthor 2009-11-17 21:53:08

0

如果有人遇到过这种情况,问题似乎只与切分方案有切线关系。即使我们在夜间运行统计信息更新,它出现的SQL Server

  1. 没有对ExtractDate创建统计
  2. 即使将该明确创建提取日期统计,未有起色,在现有一天有数据。

我们通过执行CREATE STATISTICS TABLE_A_ExtractDate_Stats ON TABLE_A WITH FULLSCAN来解决它。现在搜索前一天和随机抽样的几天似乎会产生正确的计划。