web-dev-qa-db-ja.com

SQL Serverの削除速度を改善する

巨大な本番データベースがあり、そのサイズは約300GBです。削除クエリのパフォーマンスを向上させる方法はありますか?現在、削除速度は1分あたり1〜10kですが、非常に低速です。

12
User

1つのステートメントで多数の行を削除しようとしている場合は、ログアクティビティを待機している可能性があります。だからあなたはできる:

  1. ログが適切なサイズであることを確認して、成長イベントによって速度が低下しないようにします。デフォルトでは、ログはおそらく1MBから始まり、10%増加します。成長イベントは負荷が高く、10 GBの削除をログに記録している場合、これは現在だけでなく将来的にパフォーマンスを破壊します(これはVLFに対して何をするかによります)。
  2. テーブル全体を削除する場合は、TRUNCATEまたはDROP/CREATEを使用します。
  3. テーブルのmostを削除する場合は、SELECT INTOを使用して、保持するデータを別のテーブルに入れ、次にTRUNCATEを移動して、少し後ろ。 (または単に古いテーブルを削除し、新しい名前を変更して、制約/権限を再適用するなど)
  4. 一度にすべてのデータを削除するのではなく、チャンクでデータを削除することにより、最初にログ記録の影響を最小限に抑えます。 この記事 を参照してください。一時的に単純復旧に切り替えることを検討することもできます。これにより、ログバックアップを取得する代わりにCHECKPOINTを実行するだけでログをクリアできますが、ログを元に戻して新しいフルバックアップを取得する必要があります。ログチェーンを再開します。
20
Aaron Bertrand

ヒントはいくつかありますが、どのバージョンを使用していますか?エンタープライズ版ですか?とにかく:

  1. 可能であれば、トランザクションログをより高速なディスクに移動します。
  2. whereを分析します。インデックスを使用して、削除するレコードを識別しますか?そうでない場合、インデックスを追加できますか?
  3. ドロップできるテーブルのインデックスはありますか?はいの場合、それらをドロップします。
  4. このテーブルに対して外部キーはありますか?これらは本当にあなたの削除を遅くすることができます。
  5. エンタープライズエディションがあり、ボトルネックがディスクIOである場合、行レベルでの圧縮は、少しの助けになります(または、データによってはそうではありません)。
  6. テーブルを分割できますか?ローカルインデックスとパーティションの削除はより高速になる可能性があります。
  7. アクティビティモニターを介してボトルネックの場所を調査します。

詳細を追加してください。大きなデータベースで作業する場合、有効な答えは1つではありません。

3
user_0

あなたはそれらをチャンクごとにチャンクで削除してみてください、おそらくループ内で削除します、それぞれがそれ自身のトランザクションである反復を削除し、そして各ループ反復の終わりにログをクリアします。

また、レコードを削除するためにチャンクの値として使用する番号を見つける必要があります。徹底的なテストが必要ですが、最初にUATでチャンクの値をテストできればより良いでしょう。

続行方法については、 大きな削除操作をチャンクに分割することを参照します

0
KASQLDBA

いくつかのポイントを追加しています...

  1. 述語にインデックスがあるかどうかを確認し、統計も確認してください。
  2. 多数の行を削除していて、一時テーブルオプションも必要ない場合。 tablockオプションに移動します。
  3. 特に削除トリガーの後に、トリガーがあるかどうかを確認します。

さらにヘルプが必要な場合は、使用しているクエリ、テーブル情報、およびブロック情報を投稿してください。

0
TheGameiswar

大きなテーブルに再帰的な外部キーがある場合、削除が遅くなる可能性があります。

その場合は、適切な時間を見つけ、依存サービスを無効にし、再帰的な外部キーを無効にし、大量の削除を実行してから、外部キーを再度復元します。

0
obratim