そのため、ステージングテーブルからデータを取得してデータマートに移動する簡単な一括挿入プロセスがあります。
このプロセスは、「バッチごとの行」のデフォルト設定を使用した単純なデータフロータスクであり、オプションは「tablock」および「チェック制約なし」です。
テーブルはかなり大きいです。 587,162,986、データサイズは201GB、49GBのインデックススペース。テーブルのクラスター化インデックスは次のとおりです。
CREATE CLUSTERED INDEX ImageData ON dbo.ImageData
(
DOC_ID ASC,
ACCT_NUM ASC,
MasterID ASC
)
主キーは次のとおりです。
ALTER TABLE dbo.ImageData
ADD CONSTRAINT ImageData
PRIMARY KEY NONCLUSTERED
(
ImageID ASC,
DT_CRTE_DOC ASC
)
現在、SSIS経由のBULK INSERT
の実行が非常に遅いという問題が発生しています。 100万行を挿入するには1時間。テーブルに入力するクエリは既に並べ替えられており、入力するクエリの実行には1分もかかりません。
プロセスが実行されているとき、クエリはBULK挿入を待機しており、5〜20秒かかり、待機タイプPAGEIOLATCH_EX
を示しています。プロセスは一度に約1,000行しかINSERT
できません。
昨日、このプロセスをUAT環境に対してテストしているときに、同じ問題が発生しました。私はプロセスを数回実行し、この遅い挿入の根本的な原因が何かを特定しようとしました。それから突然、それは5分未満で実行し始めました。だから私はそれを数回実行したが、すべて同じ結果になった。また、5秒以上待機していた一括挿入の数は、数百から約4に減少しました。
活動が大幅に減少したわけではないので、これは困惑しています。
期間中のCPUが少なくなっています。
遅いときは、ディスクでの待機が少ないようです。
プロセスが5分未満で実行されていた時間枠の間に、ディスク遅延は実際に増加します。
また、IOは、このプロセスが適切に実行されていない間ははるかに低かったです。
既に確認しましたが、ファイルが70%しか使用されていないため、ファイルの増加はありませんでした。ログファイルには、残りの50%が残っています。 DBは単純復旧モードです。 DBには1つのファイルグループしかありませんが、4つのファイルに分散しています。
だから私が疑問に思っているのはA:なぜそれらの一括挿入でこんなに長い待機時間が見られたのかB:それをより速く動かすためにどんな魔法が起こったのですか?
サイドノート。今日もがらくたのように走ります。
[〜#〜] update [〜#〜]現在パーティション分割されています。しかし、それはせいぜい愚かな方法で行われます。
CREATE PARTITION SCHEME [ps_Image] AS PARTITION [pf_Image]
TO ([FG_Image], [FG_Image], [FG_Image], [FG_Image])
CREATE PARTITION FUNCTION [pf_Image](datetime) AS
RANGE RIGHT FOR VALUES (
N'2011-12-01T00:00:00.000'
, N'2013-04-01T00:00:00.000'
, N'2013-07-01T00:00:00.000'
);
これにより、基本的にすべてのデータが4番目のパーティションに残ります。ただし、すべて同じファイルグループに移動するためです。データは現在、これらのファイル間でかなり均等に分割されています。
UPDATE 2これらは、プロセスの実行が不十分な場合の全体的な待機です。
これは、私がプロセスを実行することができた期間の待機であり、正常に実行されています。
ストレージサブシステムはローカルに接続されたRAIDであり、SAN=は関与していません。ログは別のドライブにあります。RAIDコントローラは1 GBキャッシュサイズのPERC H800です。(UATの場合)製品はPERC(810 )。
バックアップなしの単純なリカバリを使用しています。毎晩、本番コピーから復元されます。
また、データが既に並べ替えられているため、SSISでIsSorted property = TRUE
を設定しました。
原因を特定することはできませんが、BULK INSERT操作のデフォルトのバッチあたりの行数は「すべて」だと思います。行に制限を設定すると、操作がわかりやすくなる場合があります。そのため、これはオプションです。 (これからも、Transact-SQLの "BULK INSERT"のドキュメントを調べているので、SSISの場合はそうではない可能性があります。)
これは、操作をX行の複数のバッチに分割し、それぞれが個別のトランザクションとして動作するという効果があります。エラーが発生した場合、終了したバッチは宛先テーブルにコミットされたままになり、停止したバッチはロールバックされます。それが許容範囲内である場合、つまり、後で再実行して追いつくことができる場合は、それを試してください。
現在のすべての挿入を1つのテーブルパーティションに入れるパーティション関数があることは間違いありませんが、同じファイルグループ内のパーティションでパーティションを作成することがどのように役立つかはわかりません。 SQL Server 2008以降、SQLはこれを陽気にYYYY-DD-MMとして扱います:冗談ではありません:パニックしないでください。 'YYYYMMDD'に変更するだけで、fixed:またはCONVERT(datetime、 'YYYY-MM-DDT00:00:00'、126)と思います)。しかし、私は日付値のプロキシ(intとしての年、または年+四半期)を使用してパーティション分割する方がうまくいくと思います。
多分それは他の場所からコピーされたデザインか、いくつかのデータマートで複製されたデザインでしょう。これが本当のデータマートである場合、データウェアハウスからのダンプで、部署の管理者に操作するためのデータを提供します。これは、(ユーザーが)他の場所に送信するものではなく、データユーザーに関する限り、おそらく読み取り専用です。では、パーティション関数を削除できるように思えます。または、それを変更して、すべての新しいデータを明示的に4番目のパーティションに配置し、誰も気にしません。 (おそらく、誰も気にしないことを確認する必要があります。)
将来的にパーティション1のコンテンツを削除し、新しいデータ用に別の新しいパーティションを作成するという計画のように思えますが、ここではそうは思われません。少なくとも2013年以降は発生していません。
大きなパーティションテーブルへの挿入で、これと同じように散発的な極端な速度低下が発生することがあります。宛先テーブルの統計を更新してから、もう一度実行してみましたか?極端な待機時間は、不十分な統計が原因である可能性があり、テスト中のある時点で統計の更新がトリガーされた場合、速度の向上を説明します。ただ考え、検証する簡単なテスト。