約1900万件のレコードを含む大きなテーブルがあります。
主キーはuniqueidentifier
と呼ばれるID
列で、この列には非クラスター化インデックスがあります。アプリケーションはこれらのGUID値を生成します。
現在、テーブルにはクラスター化インデックスがありません。
テーブルには現在クラスター化インデックスがないため、非クラスター化インデックスからクラスター化インデックスへの変更を検討しています。これを行うことの長所と短所は何ですか?
毎日約5万回の挿入があり、削除も更新もありません。追加の詳細が必要な場合はお知らせください。
テーブルには合計24列があり、クラスター化インデックスのない5つの非クラスター化インデックスがあります。
uniqueidentifier
)datetime
)nvarchar(64)
)私は他の誰かからデータベースを継承しました。アプリケーションはこれをGUIDを主キーとして使用し、それぞれの子テーブル内の一致する外部キーとの関係を持っているため、クエリで結合にuniqueidentifier
IDを使用します。
GUIDが連続して生成されているかどうかをどのように判断しますか?それらは似ていないようです。いくつかの例は、createddate
で並べられた次のとおりです。
24A689A0-831E-4670-9204-766256C58E43
ED001C69-11BA-430D-ACF9-3C3CADF3B400
768E5497-4F48-4C65-87D9-E9C27066708E
少し調べてみると、uniqueidentifier
列はクラスター化インデックスの候補として適切ではないようです。そのため、次のことを行う必要があるかどうか疑問に思っています。
追加の詳細情報を提供できるかどうかをお知らせください。この決定を行うための考慮事項について、誰かが私にいくつかのガイダンスを与えることができるならば、私はそれを大いに感謝します。
順次GUID=生成に切り替えない限り、GUIDをクラスター化インデックスキーとして使用する必要はありません。したがって、選択肢は
1)ID列をクラスター化インデックスキーにします。これにより、IDでの結合と検索が最適化されますが、それらはまれなようです。
2)SQL 2016+の場合、ヒープをクラスター化列ストアインデックスに置き換えます。これにより、データが圧縮され、テーブルスキャンが最適化されます。おそらく、他のインデックスの一部を削除できる程度です。
3)最も使用されている非クラスター化インデックスを選択し、クラスター化インデックスにします。
4)ヒープのままにしておきます。
いずれの場合でも、GUIDを外部キーとして使用する「子テーブル」は、その外部キー列をクラスター化された主キーの先頭列として持つことでメリットが得られる場合があります。
このuniqueidentifier
フィールドをこのテーブルのクラスタリングキーとして使用することはお勧めしません。あなたは言及しました:
削除も更新もない、毎日約5万回の挿入を取得しています
これをテーブルのクラスター化インデックスにすることは、テーブル全体がそのフィールドによって順序付けられることを意味します。したがって、挿入が行われるたびに、SQL Serverはインデックス内のその場所にシークし、新しい行をテーブルのその位置に挿入する必要があります。
そして、新しい行を挿入する必要があるデータページにスペースがない場合、スペースを空けるためにデータを移動する必要があります。
理想的には、クラスタリングキーは小さく、一意で、常に増加します。 uniqueidentifier
は間違いなく「増え続ける」基準を満たしていません。
ワークロードの「書き込み」部分は挿入のみ(削除や更新なし)のように聞こえるため、このテーブルにはヒープ(クラスター化インデックスがまったくない-現在の状態)が適しています。 SELECTクエリが許容範囲内で実行されている限り。
遅い選択クエリで問題が発生している場合は、それらをサポートするために非クラスター化インデックスを追加するか、上記の要件を満たすクラスター化インデックスを選択する必要があります。