まず、背景について説明します。私は SSIS 初心者で、2 つ目のデータ インポート プロジェクトを完了したところです。
パッケージは非常にシンプルで、タブで区切られた ~30,000 レコードの顧客値ファイルを ADO レコードセット変数にインポートするデータフローで構成されています。この変数は、それぞれから値を渡す SQL を実行する ForEach ループ コンテナーを強化するために使用されます。レコードセットの行。
最初の ~21,000 レコードのインポートは、失敗するまでに 59 時間かかりました! 最後の ~9,000 には、さらに 8 時間かかりました。はい、合計67時間!
SQL は、レコードが既に存在するかどうかを判断するためのチェック、新しいパスワードを生成するためのプロシージャへの呼び出し、および顧客データをシステムに挿入するための別のプロシージャへの最後の呼び出しで構成されます。最後の手順はレコードセットを返しますが、私は結果に無関心なので無視しました。SSIS がレコードセットを破棄するかどうかはわかりません。これがデータをシステムに取り込む最も遅い方法であることは承知していますが、これほど遅くなるとは思っていませんでした。また、最後の ~9,000 を処理している間に 3 分の 2 で失敗することもありませんでした。
ローカル マシンで約 3,000 レコードのサブセットをテストしたところ、パッケージ実行ユーティリティは、各挿入に約 1 秒かかっていると報告しました。ちょっとした簡単な計算と提案は、合計インポートの実行に約 8 時間かかるということでした。SSIS と RBAR の実行について読んだことを考えると、長い時間のように思えました。サーバーがかなり強力なので、最終的なインポートは少し速くなると思いました。私はリモートでサーバーにアクセスしていますが、これが問題になるとは思っていませんでした。過去に、シンプルな ADO 接続を使用する特注の C# コンソール アプリケーションを使用してインポートを実行したことがあり、それほど遅く実行されたことはありませんでした。
当初、宛先テーブルは存在チェック用に最適化されていませんでした。これがパフォーマンスの低下の原因である可能性があると考えました。テーブルに適切なインデックスを追加して、テストをスキャンからシークに変更しました。これにより、パフォーマンスの問題が解消されることを期待しています。奇妙なことに、目に見える効果はないように見えました。
システムにデータを挿入するために sproc を使用する理由は、一貫性のためです。これは、データが Web フロントエンドを介してシステムに挿入された場合と同じ経路を表します。また、データの挿入により、多数のトリガーが起動され、データベース内の他のさまざまなエンティティが更新されます。
ただし、このインポート中に発生していて、頭を悩ませているのは、パッケージ実行ユーティリティの出力で報告されている SQL バッチの実行時間が、実行中に対数的に増加していることです。最初は 1 秒未満の実行時間でしたが、インポートの過程で 20 秒を超えて終了し、最終的にインポート パッケージは単純に完全に停止しました。
Google と StackOverflow に感謝しますが、これらの症状を説明するものは何も見つかりませんでした。
うまくいけば、そこにいる誰かがいくつかの手がかりを持っています。
ありがとう
ErikE への返信: (これをコメントに収めることができなかったので、ここに追加しました。)
エリック。あなたのリクエストに応じて、3,000 項目のテスト ファイルをそのペースで実行しながら、データベースに対してプロファイラーを実行しました。
SSIS を使用して、プロファイラーに表示されるコードに目に見える違いを挿入する方法を簡単に理解できなかったので、実行全体でプロファイラーを実行しました。これに関連してオーバーヘッドが発生することはわかっていますが、理論的には、実行中は多かれ少なかれ一貫しているはずです。
アイテムごとの期間は、実行全体でかなり一定のままです。
以下は、トレースからのトリミングされた出力です。ここで行った実行では、最初の 800 が以前に入力されたデータと重複していたため、システムは実質的に何の作業も行っていませんでした (イェーイ インデックス!)。インデックスが役に立たなくなり、システムが実際に新しいデータを挿入するとすぐに、それに応じて時間がジャンプすることがわかりますが、最初の要素と最後の要素の間で、読み取り回数が変化したとしても、それほど変化していないようです。最大の項目です。
---------------------------------------------- | | アイテム | CPU | 読む | 書き込み | 期間 | ---------------------------------------------- | | 0001 | 0 | 29 | 0 | 0 | | | 0002 | 0 | 32 | 0 | 0 | | | 0003 | 0 | 27 | 0 | 0 | |… | | | 0799 | 0 | 32 | 0 | 0 | | | 0800 | 78 | 4073 | 40 | 124 | | | 0801 | 32 | 2122 | 4 | 54 | | | 0802 | 46 | 2128 | 8 | 174 | | | 0803 | 46 | 2128 | 8 | 174 | | | 0804 | 47 | 2131 | 15 | 242 | |… | | | 1400 | 16 | 2156 | 1 | 54 | | | 1401 | 16 | 2167 | 3 | 72 | | | 1402 | 16 | 2153 | 4 | 84 | |… | | | 2997年 | 31 | 2193 | 2 | 72 | | | 2998年 | 31 | 2195 | 2 | 48 | | | 2999 | 31 | 2184 | 2 | 35 | | | 3000 | 31 | 2180 | 2 | 53 | ----------------------------------------------
また、一晩中、システムにインポートを完全に再実行させ、プロファイラーをオンにして、事態がどのように懸念されたかを確認しました。私のローカル マシンでは、15.5 時間でインポートの 3 分の 1 を処理することができました。トレース データを SQL テーブルにエクスポートして、統計情報を取得できるようにしました。トレース内のデータを見ると、挿入間のデルタは、処理された 1,000 レコードごとに最大 1 秒増加するため、レコードが 10,000 に達するまでに、挿入を実行するのにレコードごとに 10 秒かかります。各レコードに対して実行される実際のコードは次のとおりです。わざわざ手順を批判しないでください。SQL は独学の開発者によって書かれました。彼は、実際の開発者教育を受けた人が会社に雇われるずっと前に、もともと私たちの受付係でした。良くないことは十分承知しています。
if not exists
(
select 1
from [dbo].[tblSubscriber]
where strSubscriberEmail = @EmailAddress
and ProductId = @ProductId
and strTrialSource = @Source
)
begin
declare @ThePassword varchar(20)
select @ThePassword = [dbo].[DefaultPassword]()
exec [dbo].[MemberLookupTransitionCDS5]
@ProductId
,@EmailAddress
,@ThePassword
,NULL --IP Address
,NULL --BrowserName
,NULL --BrowserVersion
,2 --blnUpdate
,@FirstName --strFirstName
,@Surname --strLastName
,@Source --strTrialSource
,@Comments --strTrialComments
,@Phone --strSubscriberPhone
,@TrialType --intTrialType
,NULL --Redundant MonitorGroupID
,NULL --strTrialFirstPage
,NULL --strTrialRefererUrl
,30 --intTrialSubscriptionDaysLength
,0 --SourceCategoryId
end
GO
各実行間の時間差を決定した結果 (簡潔にするために切り取られています)。
---------------------- | | 行 | 行 | デルタ (ミリ秒) | ---------------------- | | 500 | 510 | | | 1000 | 976 | | | 1500 | 1436年 | | | 2000年 | 1916年 | | | 2500 | 2336 | | | 3000 | 2816 | | | 3500 | 3263 | | | 4000 | 3726 | | | 4500 | 4163 | | | 5000 | 4633 | | | 5500 | 5223 | | | 6000 | 5563 | | | 6500 | 6053 | | | 7000 | 6510 | | | 7500 | 6926 | | | 8000 | 7393 | | | 8500 | 7846 | | | 9000 | 8503 | | | 9500 | 8820 | | | 10000 | 9296 | | | 10500 | 9750 | ----------------------