5

わかりました、もう一度詳しく説明する必要があります。オンラインで記事を読みましたが、まだ決定的な答えが見つかりません。

SQL Server 2008 には、約 50,000 レコードの「コア」テーブルと、すべてのクエリで同じ方法で使用される多数の読み取りアクティビティがあります。このデータは 1 か月に 1 回更新され、1 秒間に数百回読み取られます。

データは頻繁にアクセスされるため、フィールドにクラスター化されたインデックスがあります。クラスター化インデックスが次のようになっているとします。

クラスタ化されたインデックス

Field1 int
Field2 int
Field3 int
Field4 int
Field5 int

現在、それよりも多くのデータはありません。そのため、余分な列を「含まれる列」に入れることは理にかなっていますが、SQL Server ではクラスター化インデックスに列を含めることはできません。

したがって、クラスター化インデックスと本質的に同じフィールドを持つ 2 番目のインデックスがあり、他の列は "含まれる列" です。しかし、私が読んだことから、これは冗長であると思いますか?

COVERING INDEX (非クラスター化)

Field1 int
Field2 int
Field3 int
Field4 int
Field5 int

含まれる列

Field6 varchar(96)
Field7 varchar(96)

非クラスター化インデックスには、クラスター化インデックスの列が既に定義されていますか?

もしそうなら、どのようにしてこの 2 番目のインデックスをまったく列なしで作成できますか (クラスター化インデックスに既に含まれているもの以外に)? 言い換えれば、「このインデックスはクラスター化インデックスとまったく同じです... いくつかの列が含まれています」と言いたいのです。

それとも、すべての列 (レコードを識別しない 2 つを含む) をクラスター化インデックスに入れる方がよいでしょうか? varchar 列はより頻繁に (月に 1 回ではなく 1 日に数回) 更新されるため、クラスター化インデックスから除外したかったのですが、それらは十分に深いため、インデックス ツリーは、変更が発生したときにリバランスを引き起こすのに十分です。

では、このテーブルのすべての列がテーブルに戻らずにインデックスを介して利用できるように、これらのインデックスを設定する効率的な方法はありますか?

4

4 に答える 4

5

はい - NonClustered Index は、クラスター化されたキー (テーブルにクラスター化されたキーがある場合、およびない場合は行 ID) を介してテーブル内のデータにアクセスするため、クラスター化されたインデックス フィールドが自動的に含まれます。これは、クラスター化インデックスを変更すると、すべての非クラスター化インデックスが強制的に再構築される理由でもあります。

2 つのフィールドが含まれる追加の NC インデックスは、そのインデックスが多数のクエリを満たす場合に有効である可能性がありますが、それが正しい問題を解決しているかどうかはわかりません。

クラスター化されたキー内にさらに 2 つのフィールドを含めることは理想的ではありません。現在、NC インデックス内で確認されています。そのテーブルのすべてのインデックスには、クラスター化されたキーが含まれており、各インデックスがバルクアウトされていることがわかります。

これが、クラスター化されたキーをできるだけ狭くしたい主な理由です。どちらかといえば、クラスター化されたキーを調べて、5 フィールドのクラスター化されたキーを選択する理由を尋ね、その選択が断片化につながるのでしょうか?

クラスター化されたキーに人為的な値 (ID) を使用し、一意の NC インデックスを使用して、5 つのフィールドのクラスター化されたキーでの一意性を強化することをお勧めします。

于 2011-01-02T17:01:41.320 に答える
4

クラスター化インデックスにはインクルードは必要ありません。インクルードとは、インデックス ツリーの最下位レベルに余分なデータが格納されていることを意味します。これ、クラスター化インデックス内のデータです。したがって、重複するインデックスは必要ありません

ただし、メモリ フットプリントが問題になる場合は、テーブルを縮小する必要があります。50k 行の場合、-32768 から始まる smallint 代理キーを検討します。次に、すべての NC インデックスで C キーのオーバーヘッドを削除します。これは、質問で述べたように、カバリング インデックスを使用できることを意味します。

実行計画がキャッシュされ、データがキャッシュに格納されると、クエリはメモリから取得されることに注意してください。あなたの使用は、しばらくの間キャッシュにとどまることを意味します。更新がないということは、統計主導の再コンパイルが得られないことを意味します。

ただし、データがほとんど静的である場合、パフォーマンスが懸念される場合、SQL Server を呼び出す必要はありません。キャッシュします。私のキャッシュ コメントに基づいて、おそらく最大のオーバーヘッドであるネットワーク ラウンド トリップを削除します。サーバーの負荷を軽減するために、一部のルックアップとキャッシングをクライアントにアウトソーシングしています (ピーク時の負荷で約 20 秒で 50k の書き込みがあります)。

于 2011-01-02T18:37:00.923 に答える
1

余分な列を「含まれる列」に入れるだけでも意味がありますが、SQL Server ではクラスター化インデックスに列を含めることはできません。

クラスター化インデックスには既にすべての列が含まれているため、余分な列を含めることはできません。そのため、インデックスはクラスター化されていると呼ばれます。

したがって、クラスター化インデックスと本質的に同じフィールドを持つ 2 番目のインデックスがあり、他の列は "含まれる列" です。しかし、私が読んだことから、これは冗長であると思いますか?

ええ、それはおそらく冗長です。クラスター化インデックスがメモリに収まらないまれな例外がいくつかあります。

非クラスター化インデックスには、クラスター化インデックスの列が既に定義されていますか?

おそらく: 非クラスター化インデックスには、クラスター化インデックスへのポインターが含まれています。クラスター化インデックスが一意の場合、このポインターはすべてのクラスター化インデックス フィールドで構成されます。(ほとんどの場合、これらのフィールドは主キーに対応しています。)

では、これらのインデックスを設定して、テーブルに戻らずにインデックスを介してこのテーブルのすべての列を使用できるようにする効率的な方法はありますか?

投稿した例では、クラスター化されたインデックスで十分であるように見え、テーブル ルックアップを回避するために他のインデックスは必要ありません。これを確認するには、クエリを実行し、「キー ルックアップ」または「リッド ルックアップ」操作を探します。

于 2011-01-02T17:02:07.270 に答える
1

CLUSTERED および NONCLUSTERED インデックスについて理解を深める必要があると思います。クラスタ化インデックスは、各ノードにインデックスのキー列が含まれるバランス ツリー (B ツリー) です。通常は、多くの場合に最適なオプションですが、1 つの列がインデックスのキー列になります。各行のすべてのデータは、クラスタ化インデックスのリーフ レベル (つまり、最下位レベル) に格納されます。これが、クラスター化インデックスに列を含めることができない理由です。定義により、すべての列が含まれます。

非クラスター化インデックスも B ツリー構造です。各ノードには、インデックスのキー列が含まれています。非クラスター化インデックスのリーフ レベルには、含まれる列が含まれます。キー列と含まれる列の違いは、キー列の値がインデックスの各レベルに表示され、含まれる列はリーフ レベルにのみ表示されることです。リーフ レベルには、インデックスをテーブル データにリンクするために使用されるクラスター化インデックスのキー列も含まれます。

インデックスに含める列が多いほど、インデックスは大きくなります。また、これによりパフォーマンスが低下する可能性があります。

したがって、クラスター化インデックスの場合、インデックスのキーとしてすべての列を含める必要はなく、多くの列を含める必要もありません。データはすでにインデックスの一部です。

于 2011-01-02T17:02:51.127 に答える