標籤:資料倉儲 最佳化
在沒有真正的資料倉儲資料庫之前,現在所有的資料倉儲其實都只是一個基於維度模型建立的關係型資料庫,但是資料倉儲資料庫本身有一些區別與比如OLTP資料庫的獨特特性,比如最顯著的就是資料量最大的稱為事實的表(一般都有百萬甚至上億的資料量)居於串連的中心,其周圍是很多的基數比較小的稱為維度表(可能只有幾百行資料),然後居於中心的大資料量的事實表通過外鍵串連到十幾甚至幾十個小資料量的維度資料表。
針對資料倉儲的這種獨特的性質,微軟在SQLServer 2008之後引入了專門針對資料倉儲查詢的最佳化特性:StarJoin最佳化及Few-Outer-Row最佳化。這兩種最佳化是內建在引擎中的,我們需要做的是遵從一些語句書寫方式以從這兩種最佳化中收益。
Star Join最佳化
正如我們在上面所說的,資料倉儲的定性設計模式都是中間是大資料量的事實表,周圍散布著很多的小資料量的維度資料表,它們之間使用外鍵關係彼此聯絡。而針對資料倉儲的查詢也共用著基本同樣的查詢模式:從事實表中選出幾個度量值,然後使用外鍵連結到一個或多個維度資料表,然後在維度非主鍵列上設定過濾條件及做彙總。我們稱這種模式為星形模式,
而StarJoin最佳化就是一種特定於資料倉儲查詢的最佳化,它通過探索式方法自動識別出一個查詢是針對星形模型資料庫的查詢並識別出事實表,查詢最佳化工具然後會為每個參與的維度資料表構建雜湊表,然後基於這些雜湊表構建位元影像過濾器並應用在事實表的掃描中。構建的過濾器會高效地排除應該被接下來的join操作移除的大部分行,因此需要被接下來的操作符處理的資料行會大大減少。
然後問題就是,引擎是如何檢測星形模式的呢?它使用如下的探索式方式:
1. 在具有多個join的語句中,最大的表被考慮為是事實表
2. 被考慮為事實表的表的大小必須大於某個指定最小值
3. 兩個表直接必須是inner join
4. 兩個表之間的join必須是基於單個列的並且是相等謂詞
Few-Outer-Row最佳化
該最佳化是特定於潛逃迴圈(nestedloop join),在一些資料倉儲查詢中,位於嵌套連結外部的維度資料表一般是一個帶過濾的並行掃描。但是如果過濾後只有很少的資料,尤其是如果這些資料還都是處在一個索引頁上的時候,SQLServer 2005會在單個線程中選出這些維度資料,這導致所有接下來的工作都在單個線程中完成,這會在一些提供大於1個並行度的環境上造成不平衡的問題。
SQL Server 2008會檢測這種嵌套迴圈串連,並引入了exchange操作符來將少量的外部表格的行分發到多個線程中。
資料倉儲之 - SQL Server 2008新的最佳化特性