web-dev-qa-db-ja.com

クエリを減らすためにSSISパッケージを最適化する

顧客の注文を「レベル」(シルバー、ゴールドなど)に関連付ける必要があります注文時

CRM server::CRM db::CRM table
----------
CustomerID   PreviousLevel    NewLevel    NewLevelGrantedOn

Order server::Order db::Order table
----------
OrderID     CustomerID    OrderPlacedOn

SSISパッケージで、私はこれを行いました。

  1. Order dbに対してSQLを実行して、注文を抽出し、オブジェクト変数に入れます。
  2. 「foreachcontainer」を使用して各注文をループします。ここにデータフロータスクを配置しますselect top 1 * where CustomerID = ? and LevelGrantedOn < ? order by LevelGrantedOn desc CRMデータベースからデータを抽出し(両方のパラメーターはステップ1から取得)、いくつかの列を派生させ、出力を別のテーブルに書き込みます。

Dbの順序には2万を超えるレコードがあります。これは、データフロータスクが2万回を超えて実行されることを意味します。 CRMデータベースも2万回以上クエリされます。これらを行うには1時間以上かかります。

いくつかの組み込み機能を利用してこれらを高速化できますか(または「スマート」な方法で実行できますか)?そして、ETLおよび/またはSSISのコンテキストでは、1時間は長い時間ですか?

3
Ryan

Foreach列挙子を使用せずにこれを実現できます。これを実現するには、1つのデータフロータスクを使用するだけです。

パッケージの構築

まず、データフロータスクを制御フローに追加します

1。 OLEDBソース

DataFlowタスクで、注文テーブルから読み取るOLEDB Sourceを追加します(Execute SQL Taskで使用されるのと同じコマンド(質問の最初のステップ)

Select * FROM Order

また、customerテーブルから読み取る2番目のOLEDB Sourceを追加します。

select * FROM CRM

2。ソート

各OLEDBソースの後に、ソースコンポーネントを追加します。

  1. 最初の(順序テーブル)は、ソートするためにCustomerID列とOrderID列を選択し、ソートタイプを昇順として選択する必要があります
  2. 2番目(顧客テーブル)は、CustomerID(sort type = ascending)およびLevelGrantedOn(sortを選択する必要がありますタイプ=降順)ソート用の列

3。マージ結合

マージ結合コンポーネントを追加して、ソートされた両方の出力を結合します。結合キーとして両方の出力からCustomerID列を選択し、両方のテーブルから必要な出力列を選択します

4。条件付き分割

マージ結合後、条件付き分割を追加して、次の式に一致する行のみをフィルタリングします

[LevelGrantedOn] < [orderdate]

5。スクリプトコンポーネント

使用する必要のある最後のコンポーネントは、各customerIDの最初の行のみを取得するスクリプトコンポーネントです(両方のソースが適切にソートされているため、最初の行を取得するだけでSelect top 1 ... ORDER BY LevelGrantedOn desc

スクリプトコンポーネントで、タイプDT_BOOLの出力列OutFlagを追加し、次のスクリプトを使用します。

enter image description here

このスクリプトは、customerIDが初めて発生したときにOutFlagをTrueに設定します(TOP 1と同様)

    Public Class ScriptMain
        Inherits UserComponent


        Dim lstCustomerID As New System.Collections.Generic.List(Of Integer)
        Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)

            If lstCustomerID.Contains(Row.ID) Then

                Row.OutFlag = False
            Else

                lstCustomerID.Add(Row.ID)
                Row.OutFlag = True


            End If



        End Sub

    End Class

6。条件付き分割

2番目の条件付き分割を追加して上位1行をフィルタリングします。

[OutFlag] == True

7.OLEDB宛先

条件付き分割出力をOLEDB変換先に接続し、列をマップします。

データフロータスクは次のようになります

enter image description here

3
Hadi