1

我有一个采用Fact Constellation Schema设计的 SQL Server 数据仓库。我必须建立一个关于 4 个对象/视图的报告:

  1. 销售实际值 - 事实表 [销售]
  2. 销售目标 - 事实表 [目标]
  3. 股票 - 事实表 [库存]
  4. 入站 - 事实表 [中转]

所有对象/视图都具有相同的签名,例如:

Sales actuals: ProductID, RegionID, SalesManagerID, ..., <product data>, <region data>, ..., Quantity;
Sales targets: ProductID, --null--, SalesManagerID, ..., <product data>, -----null----, ..., Quantity;
Stocks:        ProductID, RegionID, -----null-----, ..., <product data>, <region data>, ..., Quantity;
...

为了实现这样的签名,每个对象/视图都来自一个事实表和 5-6 个维度表。维度表在对象之间共享(包含产品数据的表、包含区域数据的表……)。

计算每个视图所需的 SQL 不会超过 5-10 秒。

现在我想将它们组合在一个报告中,我正在这样做:

Select * from [Sales actuals]
UNION
Select * from [Sales targets]
UNION
Select * from [Stocks]
UNION
Select * from [Inbound]

在这里,SQL 甚至无法在 1 分钟内检索 10% 的数据。查询优化器似乎将 4 个事实表组合成一个大向量并附加维度表 - 这使系统发疯。

我想要的是保持封装的视图/对象。这意味着,引擎必须首先计算视图(4 * 5 秒 = 20 秒)。然后才应用联合操作(10 秒 + 一些开销)来检索结果。

问题:如何禁用嵌套视图中的查询优化以实现这种“计算封装”?

像编译器那样做:首先联合事实表,然后加入维度表——这是没有选择的,因为我想保持代码的可解释性和可重用性。

提前致谢!君士坦丁

4

1 回答 1

1

对于初学者,您可能想更改UNIONUNION ALL?!?

要让服务器执行您想要的操作,您可以NOEXPAND在“最终”视图中添加表格提示;但老实说,我从未见过它对整体性能有益。

我想知道如果您尝试以下方式,查询优化器会有多聪明:

;WITH facts (dimension_ids & measures)
         AS (Select * from [Sales actuals]
             UNION ALL
             Select * from [Sales targets]
             UNION ALL
             Select * from [Stocks]
             UNION ALL
             Select * from [Inbound])
SELECT dimension_values, measures
  FROM facts
  JOIN dimension1 ON dim1.id = facts.dim1_id
                 AND dim1.property = @filter_dim1 
  JOIN dimension2 ON dim2.id = ...

etc...

它可能会做你想做的事,虽然我不相信它会比

SELECT dimension_values, measures
  FROM [Sales actuals] fct
  JOIN dimension1 ON dim1.id = fct.dim1_id
                 AND dim1.property = @filter_dim1 
  JOIN dimension2 ON dim2.id = ...

UNION ALL 

SELECT dimension_values, measures
  FROM [Sales targets] fct
  JOIN dimension1 ON dim1.id = fct.dim1_id
                 AND dim1.property = @filter_dim1 
  JOIN dimension2 ON dim2.id = ...

UNION ALL
etc...

哪个——按照你的解释——是你所遇到的并且显然表现很糟糕?

PS:我知道这听起来很“基本”,但是您是否先运行 sp_updatestats ?

于 2014-01-27T21:01:53.363 回答