毎日約35,000,000行のファイルを受け取るC#アプリケーションがあります。ファイルを開き、個々のレコードを個別に解析し、フィールドの一部をフォーマットしてから、一度に1つのレコードをテーブルに挿入します。実際には遅いですが、それは期待していますが、私はそれを最適化するように求められています。大容量シングルレコードインサートのためのMSSQLの最適化
すべての最適化をSQLにのみ含める必要があることを指示しました。つまり、プロセスまたはC#コードに変更はない可能性があります。私は、SQLの変更のみに制限されている間に、このプロセスをどのようにスピードアップできるかについてのアイディアを思いついています。私は試してみたいアイデアがいくつかありますが、前にこの状況で自分自身を見つけた人からのフィードバックも欲しいと思います。
アイデア: 1.テーブルのクラスタード・インデックスを作成して、ファイルのテール・エンドで常に挿入が行われるようにします。ファイル内のレコードは日時順に並べ替えられ、現在のテーブルにはクラスタ化インデックスがありません。これは有効なアプローチのようです。
どうにかしてロギングオーバーヘッドを減らします。このデータは本質的に揮発性であるため、ロールバックできることは大したことではありません。プロセスが途中で途切れたとしても、プロセスを再起動するだけです。
隔離レベルを変更します。おそらく、順次レコードの挿入に適した分離レベルがあります。
接続時間を短縮します。 C#アプリケーションは、各インサートの接続を開閉しています。 C#コードを変更することはできませんが、おそらく、オーバーヘッド/接続時間を短縮するというトリックがあります。
私の記事を読んで、価値があると思うアイデアを捨ててくださった方々に感謝します。
おかげで、 ディーン
['BULK INSERT'](https://docs.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql)はおそらく最適な解決策ですカスタムSSISパッケージ – lad2025
ログのオーバーヘッドを減らすために、アプリケーションが単一ステートメントトランザクションを使用している場合は、耐久性の遅延が考えられます。 –
#1で述べたクラスタ化インデックスを除くすべてのインデックスを削除します。ダビデが言及したように耐久性の遅延やハードウェア(SSDのログファイルなど)を除いて、ログのオーバーヘッドを減らすために行うことはありません。 Re#3では、デフォルトのREAD_COMMITTED分離レベルが最もよく機能します。デフォルトの接続プーリングは、オープン/クローズオーバーヘッドを軽減します。他の接続管理方法ではコードの変更が必要です。これらの変更は、わずかなパフォーマンス改善のみを提供します。 SqlBulkCopyまたはテーブル値のパラメータを使用すると、数千倍ではなく数千分の1の利益を得ることができます。 –