我有一个带有事实星座模式设计的Server数据仓库。我必须在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秒)。然后应用Union操作(10秒+一些开销)检索结果。
问:如何在嵌套视图中禁用查询优化以实现这种“计算封装”?
就像编译器所做的那样:先合并事实表,然后加入维度表,这是没有选择的,因为我想保持代码可解释性和可重用性。
提前感谢!康斯坦丁
发布于 2014-01-27 21:01:53
首先,您可能希望将UNION转换为UNION ALL ?!?
要让服务器做您想做的事情,您可以在“final”视图中添加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了吗?
https://stackoverflow.com/questions/21088912
复制相似问题