web-dev-qa-db-ja.com

SQL Server 2008-パーティション分割とクラスター化インデックス

ですから、私は自分のdb設計を完​​全に制御することはできないため、現在のシステムの多くの側面変更できませんがこのシナリオの目的であると言って序文にしましょう。

デザインの側面をどのように再考すべきかについてのコメントは、おそらく正しいが役に立たない:)

幅約150フィールド、行数約600mの非常に大きなテーブルがあり、多数のプロセスを実行しています。これはデータウェアハウスの状況にあるため、スケジュールされたロードプロセスの外で更新や挿入を行わないため、大量のインデックスが作成されます。

このテーブルをパーティション分割することを決定しましたが、パーティション分割テーブルのインデックス作成について懸念があります。私はパーティショニングの経験がないので、入力やリンクはありがたいです。 BOLやmsdnで自分が何を求めているのかを明確に見つけることができませんでした。

現在、我々はIncidentKeyと呼ばれるフィールドでクラスター化しています。これはvarchar(50)であり、一意ではありません-同じIK(コメントしてください)。多くの場合、古いIncidentKeyレコードで新しいデータを取得するため、シーケンシャルでもありません。

パーティションが正しく機能するためには、クラスター化インデックスキーにパーティションフィールドIncidentDateを含める必要があることを理解しています。 IncidentKey, IncidentDateになると思います。

問題は、「新しい」パーティションのレコードがクラスタードインデックスの「古い」パーティションのレコードの前にある場合、クラスター化インデックスのメカニズムがパーティションテーブルの2つの部分のキーでどのように機能するかです。

たとえば、5つのレコードがあります。

IncidentKey    Date

ABC123        1/1/2010
ABC123        7/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010
XYZ999        7/1/2010

ABC123, 2/1/2011の新しいレコードを取得する場合は、クラスター化インデックス[〜#〜] before [〜#〜]XYZ999, 1/1/2010に含める必要があります。これはどのように作動しますか?

断片化とポインタを想定していますが、物理ストレージと、デュアルパートキーを持つパーティションテーブルの非パーティションクラスタインデックスの構成に関する情報を見つけることができません。

16
JNK

パーティションテーブルは、実際には、個々のテーブルをつなぎ合わせたものに似ています。したがって、IncidentKeyによるクラスタリングとIncidentDateによるパーティション分割の例では、パーティション分割関数がテーブルを2つのパーティションに分割して、2010年1月1日がパーティション1と7/1 /にあるとします。 2010年はパーティション2です。データはディスク上に次のように配置されます。

Partition 1:
IncidentKey    Date
ABC123        1/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010

Partition 2:
IncidentKey    Date
ABC123        7/1/2010
XYZ999        7/1/2010

低レベルでは、実際には2つの異なる行セットがあります。 all行セットを1つにまとめてシーク、スキャン、および更新するプランを作成することにより、単一のテーブルのような錯覚を与えるクエリプロセッサです。

非クラスター化インデックスの行には、対応するクラスター化インデックスキーがあります。たとえば、ABC123,7/1/2010。クラスタ化インデックスキーには常にパーティション化キー列が含まれているため、エンジンは常に、クラスタ化インデックスのどのパーティション(行セット)でこの値を検索するか(この場合はパーティション2)を認識します。

ここで、パーティション化を処理するときは常に、NCインデックスを整列するか(NCインデックスはクラスター化インデックスとまったく同じようにパーティション化される)または非整列化(NCインデックスは非パーティション化されるか、クラスター化インデックスとは異なるようにパーティション化される)かを考慮する必要があります。非境界整列インデックスはより柔軟ですが、いくつかの欠点があります。

  • 非整列インデックス 大量のメモリが必要 特定のクエリプランの場合
  • 非整列インデックスは、効率的なパーティション切り替え操作を妨げます

アラインメントされたインデックスを使用すると、これらの問題は解決しますが、この物理的なストレージ設計のオプションがデータモデルに波及するため、独自の一連の問題が発生します。

  • アライメントされたインデックスは、一意の制約を作成/適用できなくなることを意味します(パーティション列を除く)
  • パーティションテーブルを参照するすべての外部キーは、リレーションにパーティションキーを含める必要があります(パーティションキーは、アライメントのため、everyインデックスにあるため)。これには、すべての分割テーブルを参照するテーブルには、分割キー列の値が含まれています。 Orders-> OrderDetailsを考えてください。OrdersにOrderIDがあり、OrderDateによってパーティション化されている場合、外部キー制約を適切に宣言するために、OrderDetailsにはOrderIDだけでなくalsoOrderDateも含める必要があります。

私が見つけたこれらの影響は、パーティショニングを導入するプロジェクトの最初にめったに呼び出されませんが、それらは存在し、深刻な結果をもたらします。

アライメントされたインデックスがまれまたは極端なケースであると思われる場合は、これを考慮してください。多くの場合、ETLとパーティション分割ソリューションの要は、ステージングテーブルの迅速な切り替えです。スイッチイン操作には、整列されたインデックスが必要です。

ああ、もう1つ:外部キーに関する他のすべての議論と、パーティション化列の値​​を他のテーブルに追加することの波及効果は、joinsにも等しく当てはまります。

18
Remus Rusanu

クラスタ化インデックスに複数のパーティションがある場合、各パーティションには、その特定のパーティションのデータを含むBツリー構造があります。たとえば、クラスター化インデックスに4つのパーティションがある場合、4つのBツリー構造があります。各パーティションに1つ。参照 クラスター化インデックス構造

パーティションインデックスに関する特別なガイドライン

パーティションインデックスの特定のパーティションを再構築できます。

例えば.

ALTER INDEX IX_TransactionHistory_TransactionDate
ON Production.TransactionHistory
REBUILD Partition = 5;
GO
9
Mitch Wheat