データベースを縮小しても大丈夫ですか?


43

シュリンクは悪魔です。ページの順序を逆にし、皮膚がん、データの断片化、地球温暖化の原因となります。リストは続きます...つまり、100 GBのデータベースがあり、50 GBのデータを削除するとします。1つのテーブルではなく、データベース全体のレベルで古いデータを削除し、90%をカバーします。テーブル-これはデータベースを縮小するための適切なユースケースを構成しますか?

そうでない場合、データベースからこのような高い割合のデータを削除した後に家をきれいにするために取る適切な手順は何ですか?インデックスの再構築と統計の更新の2つを考えることができます。ほかに何か?

回答:


13

再編成と縮小は決して推奨されません。

データベースがオフラインで提供しているアプリを使用できる場合、縮小前にすべてのインデックスとプライマリ/外部キー制約を削除することにより、プロセスを高速化し、インデックスの断片化を減らすことができます(これにより、移動するデータが少なくなりますデータページは現在存在しないインデックスページではなくシャッフルされ、プロセスが高速化されます)、すべてのインデックスとキーが再作成されます。

縮小後にインデックスを再作成すると、インデックスが大幅に断片化されることはなくなり、縮小中にインデックスを再構築しても、後で断片化を引き起こす可能性のあるファイル内のページ割り当てに多くの小さな「穴」が残らないことを意味します。

アプリケーションをオフラインにできる別のオプションは、すべてのデータを同じ構造の新しいデータベースに移行することです。ビルドプロセスが安定している場合、現在のDBから空のDBをすばやく作成できます(現在のDBから作成しない場合は、現在のDBのバックアップを復元し、テーブル内のすべてのコンテンツを切り捨て/削除し、完全に縮小します)。

宛先のすべてのインデックスを削除し、後で再作成することをお勧めします。これは、多くのインデックス付きデータ(この場合は100%)を変更する場合により効率的であるためです。コピープロセスを高速化するには、ソースとは別の物理ドライブにある宛先データベースのデータファイルを使用します(SSDを使用している場合は、頭の動きを減らす必要はありません)、それらを移動できます完了したら、ソースの場所に移動します。

また、(ソースのコピーを空白にするのではなく)宛先を新規として作成する場合、現在のすべてのデータと数か月分の成長を含む初期サイズで作成します。これにより、データコピーが少し速くなります。プロセス全体で新しいスペースが割り当てられることはありません。

データを新しいデータベースに移行すると、縮小操作の意図したアクションが複製されるため、これは縮小を使用するよりも優れている可能性がありますが、断片化ははるかに少ない可能性があります(再編成と縮小の意図しない結果です)。縮小は、ファイルの終わり近くからブロックを取得し、それらを最初の近くの最初のスペースに配置するだけで、関連するデータをまとめる努力をしません。

後で部分的に使用されるページが少なくなる可能性が高いため、結果はスペース的にも効率的であると思われます。縮小は部分的に使用されるページを移動するだけで、特にテーブルのクラスター化キー/インデックス(テーブルに1つがある)の順序で宛先に挿入し、他のインデックスを作成する場合、データを移動するとページ全体になりやすくなりますデータがすべて移行された後。

もちろん、アプリをまったくオフラインにできない場合は、縮小を実行するだけが唯一のオプションなので、本当にスペースを取り戻す必要がある場合は、それに合わせてください。データ、アクセスパターン、一般的なワーキングセットのサイズ、サーバーに搭載されているRAMの容量などによっては、余分な内部フラグメンテーションが最終的にそれほど重要ではない場合があります。

コピー操作の場合、SSISまたはベースT-SQLのどちらでも同様に機能します(SSISオプションの効率は低下する可能性がありますが、後で維持する方が簡単になる可能性があります)。インデックスとともにFKリレーションシップを最後に作成する場合、どちらの場合でも「テーブルごとにコピー」を行うことができます。もちろん、1回限りのシュリンク+再編成もおそらく大丈夫ですが、私は人々を怖がらせて、通常のシュリンクを決して考えないようにします!(私は人々が毎日それらをスケジュールすることを知っています)。


16

データベースは再び大きくなりますか?その場合、ファイルサイズを小さくしてからデータを追加すると、ファイルは再び大きくなるだけなので、縮小操作に費やす労力は無駄になります。トランザクションはその成長が起こるのを待たなければなりません。自動成長の設定が最適化されていない場合やドライブが遅い場合、この成長活動は非常に苦痛になります。

データベースを縮小する場合、解放されたディスク領域を何に使用しますか?繰り返しますが、このデータベースが再び大きくなった場合に備えてそのスペースを空けておきたい場合は、ホイールを回転させるだけです。

ファイル内にこのすべての空き領域があるので、実行を検討するかもしれないことは、インデックスを再構築して最適化されるようにすることです(そして、空き領域がある場合にこれを行うことははるかに簡単です)。小さなクローゼットと大きなベッドルームでセーターを交換しようと考えてください)。

したがって、これが主要なクリーンアップ操作であり、実際に同じレベルのデータに再び上昇しない場合を除き、そのままにして、他の最適化領域に焦点を当てます。


@Aarron Bertrandまあ、それを大きくするのに10年かかりました。ディスクをソリッドステートにしたいので、少し心配です。5GBの自動成長で60GBに縮小することを考えていました。本当にお勧めするのは、インデックスを再構築することだけでしょうか?私は人々がさらにいくつかの推奨事項があると思った。
-bumble_bee_tuna

そして、必要な場合にのみ再構築をお勧めします。ただし、ファイルを圧縮する前にそれを行います。本当に...あなたは一般的なケースでは、パフォーマンスの最適化を提供するいくつかの空き領域を持つだろうというのが私の頭の上から何も考えることはできません
アーロン・ベルトラン

2

スペースが不足していて、データがそれほど大きくならない場合は縮小しますが、通常の成長を可能にする適切なフィルファクターでインデックスを再構築します。

最終的な目標が実際にバックアップサイズを削減することである場合は、トランザクションログを消去する包括的なバックアップ戦略を実装し、dbをバックアップするときに圧縮オプションを使用してください。

通常、5GBを頻繁に増やすと予想されない限り、5GBの自動拡張はお勧めしません。そうしないと、断続的なパフォーマンスの問題が発生する可能性があります。データサイズは最初に、たとえば1年に必要と思われるサイズに設定する必要があり、自動成長はテストしたサイズに設定する必要があります。これは動作パフォーマンスに影響しません。参照してください。DOはSQL Serverではそのデータベースの圧縮]ボタンをタッチしていません!マイク・ウォルシュ。

縮小する前にインデックスを再構築すると、インデックスのレイアウトが不適切になります。再構築してから縮小するのは良くありません。縮小すると、インデックスが破損してスペースが回復するため、事前に再構築してから縮小しても意味がありません。Thomas LaRockによるAuto Shrinkを使用するタイミング参照してください。


インデックスを縮小してから再構築すると、再構築に使用されるデータのコピーに対応するために、データファイルを再び大きくする必要があります。この場合、元のデータファイルほど大きくはありませんが、それでも成長し続けるため、逆効果になります。空きスペースがあるときに再構築する方が高速で(自動拡張は不要)、通常、インデックスの新しいコピーのページをどのようにレイアウトするかを提案するよりも優れています。ほとんどの場合、これは全体的に短くなると思います同じまたはより良いディスク容量の回復につながります。おそらくいくつかのテストのための時間。
アーロンバートランド

そしてもちろん、これは、残っているデータのインデックスを実際に再構築する必要があることを前提としています-すでにかなり良い形になっているかもしれません。
アーロンバートランド

1

これが縮小後に再インデックスするよりもうまくいくかどうかはわかりませんが、別のオプションは、適切なサイズの新しいデータファイルを作成し、すべてのデータをそこに移動することです。その場合、実際のデータサイズがわかるように、最初にインデックスの再作成を行います。1つの問題は、これがプライマリデータファイルの最初のファイルである場合、空にできるとは思わないことです。あなたはそれを縮小し、その後データを戻すことができるはずです。そうすればページの反転を避けることができます。ただし、ソリッドステートへの移行を検討している場合は、とにかく大きな違いはありません。


1

この方法に遅れて戻ってくる。それでも、私たちはテスト環境でのシュリンクの使用についても長い間熟考し、テストしてきました。トピックごとに、そこにあるシュリンクが実行可能な選択肢である回。しかし、それをいつどのように適用するかを知ることは、長期と短期の両方で適切に実行するために不可欠です。

このシナリオでは、圧縮、パーティション分割、アーカイブ、冗長データの古い削除など、多数の変更を大規模なDBに最近追加しました。その結果、プライマリデータファイルの使用済み部分は、以前の半分以下になりました。しかし、そのすべての荷物を持ち歩くことのポイントは何ですか?特にWeb上のいくつかの記事とは反対に、データファイルのサイズはバックアップ/復元期間と直接相関します。これは、多くの記事が想定しているのとは異なり、実際のシナリオでは、削除したものだけでなく、特定のページに多くのデータがロードされるためです。

さらに重要なことに、これは縮小の素晴らしいシナリオを開きます。

  1. データベース内のすべてのオブジェクトとそのファイルグループを検索するスクリプトを作成し(多数のオンライン例)、これを使用してドロップ句を作成し、インデックスと制約のすべての定義を作成します。
  2. 新しいファイルとファイルグループを作成し、それをデフォルトにします。
  3. すべての非クラスター化インデックスを削除します(一部のインデックスは制約になる場合があります)。
  4. DROP_EXISTING = ONを使用して、新しいファイルグループにクラスター化インデックスを作成します(これは、多くの代替手段と比較して、非常に高速で最小限に記録される操作です)。
  5. 非クラスター化インデックスを再作成します。
  6. 最後に、古いデータファイル(通常はPRIMARY)を圧縮します。

このように、そこに残っている唯一のデータは、DBのシステムオブジェクト、統計、手順、その他です。縮小は非常に速く、はるかに高速である必要があります。また、適切に適切に作成され、将来の断片化のリスクを最小限に抑えるメインデータオブジェクトのインデックスメンテナンスをさらに行う必要はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.