在SSIS的數據流組件中,SSIS引擎使用Merge Join組件和 Lookup組件實現TSQL語句中的inner join 和 outer join 功能,Lookup查找組件的功能更類似TSQL的Exists關鍵字,只檢查數據是否存在。在SSIS引擎中,任何流經數據流(Data Flow)組件的數據都會被加載到服務器內存的數據緩沖區中,數據緩沖區能夠容納的數據量決定了轉換組件的性能。
一,轉換組件的結構
1,Lookup轉換組件有一個輸入(Input),一個查找表(或叫緩存表,引用表),映射關系和多個輸出(Output)
映射關系是指Lookup轉換組件的輸入(Input)列和查找列之間的相等關系,定義了輸入和引用表之間按照什么條件進行匹配,相當於定義Join子句的On條件;在創建映射關系時,用戶需要顯式指定一個或多個映射關系,就是說,用戶需要指定哪些Input列和查找列之間具有相等關系。

Lookup組件查找的過程是:對於輸入(Input)中的每一個數據行,根據映射關系,對查找表進行全表查找;如果該數據行能夠在查找表中找到相應的鍵值,那么該數據行匹配成功,從“Lookup Match Output” 路徑輸出到下游組件;如果不能在查找表中找到相應的鍵值,那么該數據行匹配失敗,從“Lookup No Match Output”路徑輸出到下游組件。
由於輸入中每一個行數據都會查找整個緩存表,因此,如果將查找表數據緩存在內存中,能夠提高Lookup組件的查找性能,Lookup轉換組件提供三種緩存模式來處理查找表的數據:全部緩存在內存,部分緩存在內存中,每次都從數據源中讀取。如果查找表數據量少,請全部緩存在內存中,以提高Lookup組件的轉換性能。
Lookup組件在Full Cache模式下是無阻塞轉換,只有Lookup轉換組件在加載緩存表數據時,它才會阻塞數據流。只有當緩存表數據加載完成之后,查找轉換組件才開始運行。一旦緩存數據加載完成,數據以無阻塞的流式來處理數據。

2,Merge Join轉換組件有兩個有序的輸入(Sorted Input,使用Sort組件排序,或者在數據庫中使用Order by 子句排序)和一個輸出(Output)
在Merge Join轉換組件配置聯接條件(inner join,left join和full join),執行連接查詢之后,輸出相應的數據。下游組件可以使用Conditional Split 轉換組件,獲取匹配成功或匹配失敗的數據。Merge Join轉換組件沒有緩存數據。

二,Lookup 轉換
1,流的特性
Lookup 轉換是非阻塞轉換,具有流式轉換的特性,能夠邊加載數據,邊對數據進行轉換處理,這意味着,當新的數據行進入Lookup轉換組件時,已經被處理完成的數據行會被傳遞到下游組件,而不會被攔截,就像水流一樣,綿綿不絕,直到所有數據處理完成。
當Lookup轉換組件處於Full Cache緩存模式時,Lookup轉換組件在將緩存表加載到內存中時,會阻塞數據流,直到所有的查找數據都加載到緩沖區后,才開始真正執行數據流任務(Data Flow Task),因此,為了提高查找轉換的性能,確保將小表作為緩存表(設置為Full Cache模式),而將大表的數據以流式輸入到Lookup轉換組件中。
當Lookup轉換組件處於Partial Cache或No Cache緩存模式時,Looup 轉換組件被識別為基於行(row-based)的轉換,流經Lookup轉換組件的數據行,需要與一個外部輸入進行交互,從而被逐一處理。鑒於基於行的處理過程,在大多數情況下無法跟上數據流處理的速度,因此,緩沖區將被攔截阻塞,直到Lookup轉換組件處理完緩沖區中的所有數據,所以,當Lookup轉換組件處於Partial Cache或No Cache緩存模式時,通常認為Lookup組件具有半阻塞性。
2,緩存模式(Cache Mode)
Lookup 轉換組件有三種緩存模式(Cache Mode):Full Cache,Partial Cache 和 No Cache。
全緩存模式(Full Cache)是指Lookup 轉換組件將緩存表中的數據全部加載到內存的數據緩沖區中,另一個輸入中的每一行數據都會流經緩沖區,執行聯接操作。
無緩存模式(No Cache)是指Lookup 轉換組件對上游輸入的每個數據行,都會執行一次查詢,檢查數據是否存在於緩存表中。 在No Cache 模式下,當每個輸入行流經Lookup 轉換組件時,該組件向數據庫中的引用表發送一條請求,查看鍵值是否匹配,這種方式性能非常低下,速度慢。
部分緩存模式(Partial Cache)是指Lookup轉換組件在MaxMemoryUsage屬性限制的內存使用量下,將最近使用過的數據緩存到內存中,一旦緩存增長過大,最少使用的緩存數據將會被丟棄。如果引用表數據量太大,而無法將其所有數據全部加載到緩存中,可以選擇Partial Cache模式。
當Package啟動時,與No Cache模式一樣,不會將數據預先加載到Lookup Cache中,當每個輸入行進入組件時,該組件使用指定的聯接鍵以及指定的查詢來嘗試查找匹配的記錄。如果找到匹配項,那么及時將查找到的鍵值添加到緩存中,如果相同的鍵值再次進行查找,那么就可以從緩存中獲取匹配鍵值,從而節省了訪問外部輸入源的查詢時間。如果在緩存中沒有找到匹配的鍵值,那么組件將訪問外部輸入源,進行查詢,如果外部輸入中也沒有,那么鍵值不匹配。
MaxMemoryUsage屬性指定Lookup 轉換組件在Partial Cache模式下所使用的最大內存。
三,Merge Join 轉換
1,Merge Join是半阻塞轉換
在向下游組件傳遞數據之前,Merge Join轉換組件需要將數據流攔截在緩沖區中一段時間,直到來自兩個輸入的鍵值匹配成功,Merge Join轉換組件才將數據行向下游組件傳遞。
2,Merge Join使用少量的內存
相比於Lookup 轉換組件,Merge Join轉換組件只使用較少的內存,基本上不會緩存數據,因為只需要維護內存中用來聯接兩個輸入所需要的少量數據。當內存容量有限或者,輸入的數據量過大時,Merge Join轉換組件是一個非常有用的組件,但是,Merge Join轉換組件有一個前提條件,輸入的數據流必須是有序的,由於SQL Server數據庫引擎的排序功能非常強大,因此,推薦將Merge Join的輸入數據流在SQL Server 數據庫中進行排序,避免使用Sort組件對數據流進行排序。
四,緩存連接管理器
Lookup 轉換組件是唯一使用CCM(Cache Connection Manager,簡稱CCM)對數據進行緩存的組件,CCM能夠從任意數據源中填充 Lookup轉換組件的緩存。如果Lookup 轉換組件處於Full Cache 模式下,那么使用CCM加載緩存數據將會提高轉換性能。在同一Package中,如果多個Lookup 轉換組件使用相同的緩存數據集,使用CCM緩存數據,這些Lookup轉換組件可以共享相同的緩存,這樣,就不需要多次加載相同的緩存數據。
五,在數據源組件中,指定數據流是已排序的
step1,有序的輸入
在獲取數據時,使用Order By子句對數據進行排序,使數據在進入數據源組件時,是已經排過序的。
from dbo.data_source order by UserID asc,ProfileID desc
step2,設置IsSorted屬性為True
打開OLE DB Source 數據源組件的高級編輯器(Advanced Editor),點擊“OLE DB Source Output”,將“Common Properties”列表中的IsSorted屬性設置為True。該屬性不會對數據進行排序,只是標識數據流是有序的。

Step3,SortKeyPosition屬性標識已排序的列和其排序的方向
在SortKeyPosition屬性中,正表示升序,負表示降序,絕對值表示位置序號,位置從1開始,依次遞增。
打開“Output Columns” 輸出列列表,將UserID的SortKeyPosition屬性設置為1,ProfileID的SortKeyPosition屬性設置為-2。

參考文檔:
