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秒+一些開銷)來檢索結果。

問題:如何禁用嵌套視圖中的查詢優化來實現這種「計算封裝」?

像編譯器一樣做:首先聯合事實表,然後加入維表 - 因爲我想保持代碼的可解釋性和可重用性,所以沒有選擇。

提前致謝! 君士坦丁

+0

我想如果你選擇4個臨時表,然後聯合這些表,你可能會得到你想要達到的。 –

+2

嘗試將'UNION'更改爲'ALLION ALL'。聯盟可以花費很多時間,因爲它可以消除重複。 – valex

回答

0

對於初學者,您可能想要將UNION更改爲UNION 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?