たとえば、次のように構造化されたテーブルがあるとします。
ID1 int
ID2 int
ID3 int
DTM datetime
ID1、ID2、およびID3を含めた場合にのみ、テーブルに一意のクラスター化インデックスを作成できます(これらの2つを組み合わせるか、個別に行を重複させることになります)。
ID1、ID2、ID3でクラスター化インデックスを作成すると、パフォーマンスが向上しますか?または、ID1のみにクラスター化インデックスを作成し、SQL Serverにインデックスに一意化子を追加して各行を一意にしますか?
一意化子のサイズは4バイト(intと同じ)であることを知っているので、後者のインデックスを作成すると、技術的には1行あたり4バイトを節約できますが、これがクエリにどのように影響するかはわかりません。
クラスター化インデックスのパフォーマンスに関する最も重要な考慮事項の1つは、それが常に増加(または減少)することであり、変更されるものではないことです(ごくまれに例外がある場合を除く)。クラスタ化インデックスは、テーブルの物理的な順序を表します。常にインデックスの中央に挿入している場合、またはクラスター化インデックスの値を変更している場合は、SQLがデータの一部をあるページから別のページに移動してスペースを空ける必要がある不良ページ分割が発生します。新しいデータ用。これらの移動には時間がかかり、断片化が発生してパフォーマンスが低下します。
クラスタインデックスのサイズは重要ですが、最大の懸念事項ではありません。 日付列(一意性のあるもの)とint列 を使用していくつかの実験を行ったところ、クエリが日付ベースの場合でも、パフォーマンスが大幅に向上することがわかりました。
あなたへの私の提案は、ID1、ID2、ID3が常に増加している(そしてほとんど変化しない)場合、それをクラスター化インデックスとして使用することです。そうでない場合でも、一意性を適用するには、それらを非クラスター化主キーまたは非クラスター化一意キーのいずれかにします。それらが増加していない場合は、日付列を検討するか、テーブルの代理キーを作成できます。 intデータ型を使用して、それをID列にします。
サロゲートキーを作成する場合は、ID1に非クラスター化インデックスを作成して、一意のインデックスをまだ作成していないと想定して、クエリのパフォーマンスを向上させることができます。 ID2やDTMなど、頻繁に戻る必要がある場合は、これらをインデックスに含めると、パフォーマンスがさらに向上します。
提案されたインデックスは、データ制約を強制するためのものですか、それともパフォーマンスを向上させるものですか?インデックスでレコードの重複を防止する場合は、3つのフィールドすべてを含める必要があります。
ただし、パフォーマンスを向上させようとしていて、クエリが通常ID1
、別のオプションがあります。ID
だけで一意でないインデックスを作成します。これは、いずれかの一意のインデックスよりも狭く、非一意のインデックスのパフォーマンスが著しく低下してはなりません。
サンプルクエリを共有する場合は、より具体的なアドバイスを提供できます。