C# クライアントが大量のデータを SQL Server 2005 データベースに挿入すると、パフォーマンスのボトルネックが発生し、プロセスを高速化する方法を探しています。
私はすでに SqlClient.SqlBulkCopy (TDS に基づく) を使用して、回線を介したデータ転送を高速化しており、これは非常に役立ちましたが、さらに多くのことを探しています。
次のような単純なテーブルがあります。
CREATE TABLE [BulkData](
[ContainerId] [int] NOT NULL,
[BinId] [smallint] NOT NULL,
[Sequence] [smallint] NOT NULL,
[ItemId] [int] NOT NULL,
[Left] [smallint] NOT NULL,
[Top] [smallint] NOT NULL,
[Right] [smallint] NOT NULL,
[Bottom] [smallint] NOT NULL,
CONSTRAINT [PKBulkData] PRIMARY KEY CLUSTERED
(
[ContainerIdId] ASC,
[BinId] ASC,
[Sequence] ASC
))
ContainerId と BinId が各チャンクで一定で、シーケンス値が 0-n で、値が主キーに基づいて事前に並べ替えられている、平均約 300 行のチャンクにデータを挿入しています。
%Disk time パフォーマンス カウンターは 100% で多くの時間を費やしているため、ディスク IO が主な問題であることは明らかですが、得られた速度は未加工のファイル コピーよりも桁違いです。
次の場合に役立ちますか?
- 挿入中に主キーを削除し、後で再作成します
- 同じスキーマで一時テーブルに挿入し、定期的にメイン テーブルに転送して、挿入が行われるテーブルのサイズを小さく保ちます。
- 他に何か?
-- いただいた回答に基づいて、少し明確にさせてください。
Portman: データがすべてインポートされたら、その順序でデータに順次アクセスする必要があるため、クラスター化インデックスを使用しています。データのインポート中にインデックスが存在する必要は特にありません。インポートのために制約を完全に削除するのではなく、挿入中に非クラスター化 PK インデックスを使用する利点はありますか?
Chopeen: データは他の多くのマシンでリモートで生成されています (私の SQL サーバーは現在約 10 台しか処理できませんが、もっと追加できるようにしたいと思っています)。プロセス全体をローカル マシンで実行するのは現実的ではありません。出力を生成するために 50 倍の入力データを処理する必要があるからです。
Jason: インポート プロセス中にテーブルに対して同時クエリを実行していません。主キーを削除してみて、それが役立つかどうかを確認します。