12

過去 1 年間、ゆっくりと成長している大規模なデータベース (90 GB のデータ、70 GB のインデックス) があり、その成長/変更により、インデックスだけでなく、テーブル自体にも大量の内部断片化が発生しています。

(多数の)非常に断片化されたインデックスを解決するのは簡単です-断片化の程度に応じて、REORGANIZEまたはREBUILDがそれを処理します-しかし、実際のテーブルの断片化をクリーンアップする際に見つけることができる唯一のアドバイスは、クラスター化されたインデックスを追加することですテーブルに。今後テーブルにクラスター化インデックスを作成したくないので、後ですぐに削除しますが、クラスター化インデックスを使用せずにこれを行う別の方法はありますか? これを行う「DBCC」コマンドは?

ご協力いただきありがとうございます。

4

5 に答える 5

32

問題

これは一般的な問題であり、SQL Server を使用するすべての企業にとって深刻な問題であるため、明確にしておきましょう。

この問題と CREATE CLUSTERED INDEX の必要性は誤解されています。

永続的なクラスター化インデックスを持つことは、持たないよりも優れていることに同意しました。しかし、それは要点ではなく、とにかく長い議論につながるので、それは脇に置いて、投稿された質問に焦点を当てましょう.

ポイントは、Heapにかなりの断片化があるということです。あなたはそれを「テーブル」と呼んでいますが、物理的なデータ ストレージまたは DataStructure レベルにはそのようなものはありません。テーブルは論理的な概念であり、物理的な概念ではありません。これは、物理的な DataStructures のコレクションです。コレクションは、次の 2 つの可能性のいずれかです。

  • ヒープ
    とすべての非クラスター化インデックス
    とテキスト/イメージ チェーン

  • またはクラスター化インデックス
    (ヒープと1 つの非クラスター化インデックスを削除)
    と、すべての非クラスター化インデックス
    とテキスト/イメージ チェーン。

ヒープがひどく断片化されます。散在する(ランダムな)挿入/削除/更新が多いほど、断片化が多くなります。

ヒープをそのままクリーンアップする方法はありません。MS は機能を提供していません (他のベンダーが提供しています)。

解決

ただし、Create Clustered Index は、ヒープを完全に書き換えて並べ替えることがわかっています。したがって、メソッド (トリックではありません) は、 Heap の断片化を解消する目的でのみクラスター化インデックスを作成し、後でそれを削除することです。table_size x 1.25 の db の空き容量が必要です。

その際は、必ず FILLFACTOR を使用して、将来の断片化を減らしてください。その後、ヒープはより多くの割り当てられたスペースを使用し、更新による将来の挿入、削除、および行の拡張を可能にします。

ノート

  1. 断片化には 3 つのレベルがあることに注意してください。これは、クラスター化インデックスの欠如によって引き起こされる、レベル III のみのヒープ内の断片化を扱います。

  2. 別のタスクとして、別の時期に、断片化を完全に排除する永続的なクラスター化インデックスの実装を検討したい場合があります...しかし、それは投稿された問題とは別のものです。

コメントへの返信

SqlRyan:
これで私の問題に対する魔法のような解決策が得られるわけではありませんが、私の問題が SQL Server の制限の結果であり、クラスタ化インデックスを追加することがヒープを「最適化」する唯一の方法であることは明らかです。

そうではありません。それを「限界」とは言いません。

  1. ヒープ内の断片化を解消するために私が示した方法は、クラスター化インデックスを作成してから削除することです。すなわち。一時的に、その唯一の目的は断片化を修正することです。

  2. テーブルにクラスター化インデックスを (永続的に) 実装することは、全体的な断片化 (DataStructure は引き続き断片化される可能性があります。以下のリンクの詳細情報を参照してください) を減らすため、はるかに優れたソリューションです。これは、ヒープで発生する断片化よりもはるかに少ないです。

    • リレーショナル データベースのすべてのテーブル (「パイプ」テーブルまたは「キュー」テーブルを除く) には、さまざまな利点を活用するために、クラスター化インデックスが必要です。

    • クラスター化インデックスは、データを分散する列に配置する必要があります (INSERT の競合を回避します)。レコード ID 1など、単調に増加する列にインデックスを作成しないでください。これにより、最後のページで INSERT ホット スポットが保証されます。

1. すべてのファイルに ID を記録すると、「データベース」が非リレーショナル レコード ファイリング システムにレンダリングされます。SQL は便宜上のみ使用されます。このようなファイルには、リレーショナル データベースの整合性、パワー、または速度がありません。

Andrew Hill:
「フラグメンテーションには 3 つのレベルがあることに注意してください。これはレベル III のみを扱います」についてさらにコメントしていただけますか? -- 他の 2 つのレベルのフラグメンテーションは何ですか?

MS SQL と Sybase ASE には、3 つのレベルの断片化があり、各レベル内にいくつかの異なるタイプがあります。断片化を扱うときは、テーブルではなく DataStructures に注目する必要があることに注意してください (上記で説明したように、テーブルは DataStructures のコレクションです)。レベルは次のとおりです。

  • レベル I • Extra-DataStructure
    関連する DataStructure の外側、データベース全体またはデータベース内。

  • レベル II • DataStructure
    関連する DataStructure 内で、ページの上 (すべてのページにわたって)
    これは、DBA によって最も頻繁に扱われるレベルです。

  • レベル III • ページ
    関連する DataStructure 内、ページ内

これらのリンクは、断片化に関する完全な詳細を提供します。これらは Sybase ASE に固有のものですが、構造レベルでは、情報は MS SQL に適用されます。

私が示した方法はレベル II であることに注意してください。これは、レベル II および III のフラグメンテーションを修正します。

于 2010-11-02T23:11:44.097 に答える
1

テーブルの断片化を軽減するためにクラスター化インデックスを追加し、すぐに削除すると述べています。

クラスター化されたインデックスは、クラスター キーで並べ替えることによって断片化を取り除きますが、このキーは今後使用できないと言っています。これは疑問を投げかけます: なぜこのキーを使用して最適化するのでしょうか?

このクラスター化されたキーを作成して保持することは理にかなっています。明らかにデータをそのように並べ替えたい/必要としているからです。あなたは、データを変更すると、負担できないデータ移動のペナルティが発生するとおっしゃいます。FILLFACTORデフォルト値よりも低いインデックスを作成することを考えましたか? データ変更のパターンによっては、80% という低い値でもメリットがあります。この場合、ページごとに 20% の「未使用」スペースがありますが、クラスター化されたキー値が変更されると、ページ分割が少なくなるという利点があります。

それはあなたを助けることができますか?

于 2010-07-26T18:55:18.980 に答える
0

レガシーデザインのデザインに制約されているあなたの痛みを理解しています.

問題のテーブルのバックアップを別のサーバーに復元し、クラスター化インデックスを作成する機会はありますか? 一連の狭い一意の列または ID 列でクラスター化インデックスを作成すると、テーブル (データとインデックス) の合計サイズが小さくなる可能性が非常に高くなります。

私のレガシー アプリの 1 つで、すべてのデータがビュー経由でアクセスされていました。アプリケーションに影響を与えることなく、基になるテーブルのスキーマを変更して、ID 列とクラスター化インデックスを追加することができました。

ヒープを持つことのもう 1 つの欠点は、転送された行に関連する余分な IO です。

テーブルにクラスター化されたインデックスが永続的に必要であるという証拠があるかどうか尋ねられたとき、以下の記事が有効であることがわかりました

この記事はマイクロソフトによるものです

于 2010-11-22T01:38:29.187 に答える
0

NOTRUNCATEを指定してDBCC SHRINKFILE を実行すると、ヒープを圧縮できる場合があります。

コメントに基づいて、永続的なクラスター化インデックスでテストしていないようです。

これを概観すると、すべてのテーブルにクラスター化されたインデックスを持つ、1 日あたり 1,000 万の新しい行を持つデータベースがあります。削除された「ギャップ」は、スケジュールされた ALTER INDEX (およびフォワード ポインター/ページ分割) によって削除されます。

12GB のテーブルは、インデックス作成後に 2GB になる場合があります。12GB が割り当てられているだけですが、大幅に断片化されています。

于 2010-11-21T19:42:39.867 に答える
0

誰も話していない問題は、ハードドライブ自体のデータまたはログデバイスファイルの断片化です!! 誰もがインデックスの断片化と、その断片化を回避/制限する方法について話しています。

参考までに: データベースを作成するときは、.MDF の初期サイズと、拡張が必要になったときの拡張量を指定します。.LDF ファイルでも同じことを行います。これら 2 つのファイルが大きくなったときに、必要な追加ディスク領域に割り当てられたディスク領域が、割り当てられた既存のディスク領域と物理的に連続するという保証はありません。

これら 2 つのデバイス ファイルのいずれかを拡張する必要があるたびに、ハード ドライブのディスク領域が断片化する可能性があります。つまり、ハード ドライブのヘッドは、データベース内の必要なデータにアクセスするために、ハード ドライブのあるセクションから別のセクションに移動するために、より多くの作業を行う (そしてより多くの時間を要する) 必要があります。これは、小さな土地を購入して、その土地にぴったりの家を建てることに似ています。家を拡張する必要がある場合、隣の空き地を購入しない限り、利用できる土地はもうありません。ただし、その間に他の誰かがすでにその土地を購入して家を建てている場合はどうなりますか? その後、家を拡張することはできません。唯一の可能性は、「近所」で別の土地を購入し、その上に別の家を建てることです。

この状況を改善するための解決策は、「はるかに広い土地を購入し、既存の家(つまりデータベース)を取得し、それをより広い土地に移動してから、そこで家を拡張する」ことです。データベースでそれを行うにはどうすればよいでしょうか。フル バックアップを実行し、データベースを削除し (古い断片化されたデータベース (念のため) と新しいデータベースの両方を保持するための十分な空きディスク領域がない場合)、十分な初期ディスク領域が割り当てられた新しいデータベースを作成します (要求した領域が連続していることをオペレーティング システムが保証する保証はありません) し、作成したばかりの新しいデータベース領域にデータベースを復元します。はい - 面倒ですが、SQL データベース ファイルで動作する「自動ディスク デフラグ」ソフトウェアを知りません。

于 2014-02-12T18:38:06.217 に答える