web-dev-qa-db-ja.com

SQLServerの一括転送のヘルプが必要

機能を追加したい、この非常にひどく設計されたロギングテーブルがあります。問題は、それがすでにスケーラビリティの悪夢であり、追加する前に設計を修正したいのですが、それを実行するための夜間のアップグレードウィンドウしかないことです。

SQL Serverのさまざまな一括コピーオプションについて、「10分で8000万行を移動できる」と主張する記事をたくさん見てきました。しかし、これまでのところ、私のテストはそれに近いところはありません。私が見ているものを改善する方法についての提案が必要です。

アップグレードの前に、常に完全バックアップがあります。私は最終結果にのみ興味があり、巨大なトランザクションログは必要ありません。また、時間がかかりすぎたり、トランザクションログや一時ファイルでディスク領域を使い果たしたりしたくありません。

テーブルはしばらく前から存在しているため、より大きな顧客データベースでは、すでに5,000万行を超えています。各行は約350〜400バイトです。列は次のようなものです

_IdentityColID int, [type] int, [subtype] int, 
created datetime, author nvarchar(100), Message nvarchar(max)
_

デザインの問題は

  • 主要なクラスター化されたキーは_(type, subtype, created, identitycolid)_であるため、挿入の悪夢です。いたるところにブロックスプリット。そして、SELECT COUNT(*)を実行することでさえ8分ほどかかります。

  • 必要な種類のクエリをサポートするための適切なインデックスがありません

プライマリクラスター化インデックスがIdentityColIdである新しいテーブルを作成し、必要なクエリのタイプをサポートするインデックスを追加してから、既存のデータをコピーして古いテーブルを削除したいと思いました。

これまで、BCPを使用してデータを取得し、

  • BCP

  • バルク挿入

  • INSERT INTO ... FROM OPENROWSET

Bcpのエクスポートには約25分かかり、インポートにはすべて約1.3時間(約1.5時間)かかりました。 Recovery Model Simpleでは、トランザクションログは増加しませんでしたが、CPU消費量はほとんどの場合60〜65%の範囲でした。

T-SQL _INSERT INTO NewTable SELECT * FROM OldTable_を使用してみましたが、Recovery Model Simpleを使用しても、トランザクションログは100ギガになります。

From/toモデルでSSISデータインポートパッケージを使用してみましたが、正味時間は約1時間20分でした。 Recovery Model Simpleでは、トランザクションログは小さいままでした。

次に、SSIS Execute SQLTaskパッケージを試して、SSIS内で_INSERT INTO NewTable..._行を効果的に実行しました。これにより、実行時間は約1:15に短縮されましたが、リカバリモデルに関係なく、CPU消費量はそれほど多くありませんが、トランザクションログは約100ギガになりました。

最終結果を1つの新しいテーブルにしたいので、複数の結果テーブルに並列化するために読んだいくつかの記事からの提案は、有益な道ではないようです。しかし、これまでのところ、私が読んだ記事からそれらの統計に近づくことはできないようです。

誰かが私がこれを少しガチョウにする方法について何か提案がありますか?

1
user1664043

Swears-A-lot卿の返答はコメントにあったので、私は信用を与えることができませんが、彼は正しかったです。主キーを削除して新しいキーを作成することは、空の新しいテーブルをロードすることと実質的に同じか、それよりも費用がかかるという私の仮定は正しくありませんでした。

リカバリモードの設定は簡単で、主キーを削除して再作成し(再シャッフルを強制し)、その後40分ですべての新しいインデックスを追加します。これは、私が試したbcp/SSISメソッドを30分以上上回っていたので、大きな改善でした。

そして、トランザクションログは10ギガ増加しましたが、他のいくつかの実験のようにうまくいきませんでした。

1
user1664043

SSISを試したときに構成を変更しましたか? SQLステートメントでSQL実行タスクを使用することは、SSMSで同じSQLを実行することと同じです。以下は、SSISでこのプロセスを実行する概要です。もちろん、さまざまな設定を変更してテストし、環境で最適に機能するものを確認することをお勧めします。

  • データフロータスクを追加します。これに、OLE DBソースコンポーネントを追加します。「SQLコマンド」データアクセスモードを使用し、必要な列のみを含むSELECTステートメントを作成することをお勧めします。
  • OLE DBDestinationまたはSQLServer Destinationのいずれかを追加し、ソースをこれに接続します。SQLServerDestinationはパフォーマンスが向上する傾向がありますが、上のデータベースにインポートする場合にのみ使用できます。ローカルサーバー。OLE DB宛先を使用する場合は、[テーブルまたはビュー-高速ロード]オプションを使用します。これは、内部でBULK INSERTとして動作します。宛先でこれをバイパスするには、[制約のチェック]オプションのチェックを外します。
  • トランザクションログの過度の使用を回避するには、Maximum Insert Commit Size(OLE DB宛先)をデフォルトよりも低い値に変更します。 MaxInsertCommitSizeのSQLServer宛先でこれに相当します。これは、コンポーネントを右クリックし、高度なエディターの表示を選択して、[コンポーネントのプロパティ]ページに移動すると表示できます。デフォルトの0は、すべてのレコードが1回のトランザクションでコミットされることを意味します。
  • データフロータスクで、[プロパティ]ウィンドウに移動し、AutoAdjustBufferSizeをtrueに設定します。これにより、DefaultBufferMaxRowsプロパティに基づいてバッファのサイズが設定されます。これは、バッファが保持できる行数を示します。
  • 並列実行も調整できます。パッケージでは、MaxConcurrentExecutablesプロパティが実行可能なタスクの最大数を設定します。デフォルトは-1です。これは、パッケージが実行されているプロセッサの数に2を加えた数です。データフロータスクにはEngineThreadsプロパティがあり、使用できるスレッドの数を制御します。
0
userfl89