機能を追加したい、この非常にひどく設計されたロギングテーブルがあります。問題は、それがすでにスケーラビリティの悪夢であり、追加する前に設計を修正したいのですが、それを実行するための夜間のアップグレードウィンドウしかないことです。
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つの新しいテーブルにしたいので、複数の結果テーブルに並列化するために読んだいくつかの記事からの提案は、有益な道ではないようです。しかし、これまでのところ、私が読んだ記事からそれらの統計に近づくことはできないようです。
誰かが私がこれを少しガチョウにする方法について何か提案がありますか?
Swears-A-lot卿の返答はコメントにあったので、私は信用を与えることができませんが、彼は正しかったです。主キーを削除して新しいキーを作成することは、空の新しいテーブルをロードすることと実質的に同じか、それよりも費用がかかるという私の仮定は正しくありませんでした。
リカバリモードの設定は簡単で、主キーを削除して再作成し(再シャッフルを強制し)、その後40分ですべての新しいインデックスを追加します。これは、私が試したbcp/SSISメソッドを30分以上上回っていたので、大きな改善でした。
そして、トランザクションログは10ギガ増加しましたが、他のいくつかの実験のようにうまくいきませんでした。
SSISを試したときに構成を変更しましたか? SQLステートメントでSQL実行タスクを使用することは、SSMSで同じSQLを実行することと同じです。以下は、SSISでこのプロセスを実行する概要です。もちろん、さまざまな設定を変更してテストし、環境で最適に機能するものを確認することをお勧めします。
SELECT
ステートメントを作成することをお勧めします。BULK INSERT
として動作します。宛先でこれをバイパスするには、[制約のチェック]オプションのチェックを外します。Maximum Insert Commit Size
(OLE DB宛先)をデフォルトよりも低い値に変更します。 MaxInsertCommitSize
のSQLServer宛先でこれに相当します。これは、コンポーネントを右クリックし、高度なエディターの表示を選択して、[コンポーネントのプロパティ]ページに移動すると表示できます。デフォルトの0は、すべてのレコードが1回のトランザクションでコミットされることを意味します。AutoAdjustBufferSize
をtrueに設定します。これにより、DefaultBufferMaxRows
プロパティに基づいてバッファのサイズが設定されます。これは、バッファが保持できる行数を示します。MaxConcurrentExecutables
プロパティが実行可能なタスクの最大数を設定します。デフォルトは-1です。これは、パッケージが実行されているプロセッサの数に2を加えた数です。データフロータスクにはEngineThreads
プロパティがあり、使用できるスレッドの数を制御します。