インデックス付きビューが一意でないクラスター化インデックスを許可しないのはなぜですか?


12

インデックス付きビューを使用して、最もよく使用されるいくつかのビューのパフォーマンスを向上させることを検討してきました。

ただし、インデックス付きビューは、一意ではないクラスター化インデックスをサポートしていません。これは、データベース構造の残りの部分によって設定された優先順位に少し影響します。

たとえば、ここにいくつかのテーブルの簡略化したバージョンがあります。

-Groups-
Group ID    GroupName

-Users-
UserKey    UserName    FullName     GroupID

インデックスは、Groups.GroupID(非クラスター化)およびUsers.GroupID(クラスター化)にあります。クラスター化されたキーは、最も一般的には特定のグループの一連のユーザーが取得されるため、UsersテーブルのGroupIDにあります。当然、グループごとに複数のユーザーがいるため、このクラスター化インデックスは一意ではありません。

このため、この例のようにビューにインデックスを付けるときに、この優先順位に従う方法が少し不確かになります。これは、一意でないクラスター化インデックスを持つことができないためです。

ConsumableID    ConsumableVariantID AllowThresholdOverwrite FullPath    GroupID ManufacturerID  Type    ModelID
101              29                 1                       0.1.2.4.    4       3               3       2

実際には、常に一意であるこのビューの唯一の値はConsumableID列です。そのため、インデックスを配置する場所についてほとんど選択肢がありません。

通常のテーブルで許可されているのに、ビューが一意でないクラスター化インデックスを許可しないのはなぜですか?


3
このページの下部に、「ビューの最初のインデックスをクラスタ化して一意にする必要があるのはなぜですか?」というタイトルの非常に短い説明があります。しかし、詳細はあまりありません。もっと詳しい説明を聞きたいです。
スティーブペティファー

5
いくつかのコメント:1-でクラスター化できない理由はありません(GroupID, UserID)。キーの列を1つに制限しないでください。2-ビューの制限は、これが行をNCインデックスに簡単に関連付ける必要がある補足データオブジェクトであるためと考えられます。テーブルの場合、一意ではないCIキーにはintが追加されますが、実際のテーブルではないが実際のテーブルをREFLECTする必要があるため、インデックス付きビューの方が難しいと思います。
JNK、2014

回答:


22

次の説明は、このMicrosoft技術記事に記載されています

ビューの最初のインデックスをクラスタ化し、一意にする必要があるのはなぜですか?

インデックス付きビューのメンテナンス中にキーの値によってビューのレコードを簡単に検索できるようにし、重複したビューの作成を防ぐために、一意である必要があります。クラスター化されたインデックスのみが一意性を強制し、同時に行を格納できるため、クラスター化する必要があります。

SQL Serverは、デルタ代数のシステムを使用して、インデックス付きビューをベースデータと一致させます。また、1つ以上のインデックス付きビューに影響を与える各DMLクエリのビュー保守クエリプラン演算子を自動的に組み込みます。ビューに一意のクラスター化インデックスを設定すると、実装の詳細が大幅に簡素化されます。

現在の配置では、固定形状のメンテナンスオペレーターツリーの形状をベースDMLクエリツリーに組み込むことができ、直交性を提供してテストも簡素化します。最終的に、インデックス付けされたビューは、非一意のクラスター化インデックスをサポートするように1日強化される可能性がありますが、無制限の時間と無限のリソース(これらはいずれも執筆時点ではSQL Server開発チームに適用されません)があれば、すべてが可能になります。

複雑な更新クエリプランの構築がどのように行われ、微妙なバグが侵入しやすいかを示す例については、フィルターされたインデックス(インデックス付きビューに密接に関連する機能)で発生するバグのこの例を参照してくださいMERGE


2
GROUP BY句があるが、すべてのグループ化式がクラスター化インデックスのキーではないインデックス付きビューを更新しようとすると、同様のバグが発生する可能性があります。SQL Server 2014以降で有効です
。– Quassnoi

4

SQL Serverでは、すべてのインデックスキーは内部的に一意である必要があります。これは、1つの行だけをアドレス指定するロックキーを取得するために必要です。インデックスのメンテナンスにも必要です。値が1つしかない列(100%重複)のNCIを想像してください。行がテーブルから削除された場合、ストレージエンジンは対応するNCI行を見つけて削除する必要があります。すべてのNCI行が区別できない場合、これは不可能です。

したがって、ビューのCIは、エンジンが機能するために(内部で)一意である必要があることがわかります。

インデックスを一意にしない場合、SQL Serverは内部的にインデックスを一意にします。ヒープテーブルのNCIの場合、行ブックマークを追加します。一意でないCIの場合は、一意識別子列を追加します。CIを含むテーブルのNCIの場合、自分でまだ指定していないCIキー列を追加します(これには、一意化記号が含まれる場合があります)。

インデックス付きビューの場合に追加できる明確な列はありません。したがって、SQL Serverはこれを自動的に実行できません。

通常、ビューにCIで使用する一意の列のセットを持たせるためにどの列を追加できるかは、人間には明らかです。これらは通常、基になるテーブルの1つのPK列またはCI列です。ビューにGROUP BY通常、グループ化キーのインデックスがあります。


2
この回答の言い回しを改訂することを強くお勧めします。元の質問に関する有効なポイントが含まれていますが、一意でないすべてのインデックスに一意化子が含まれていることを示唆しているように見えますが、そうではありません。
スパゲッティ

@spaghettidbaありがとう、私はそれに気づきませんでした。それが今より良いことを願っています。
usr

申し訳ありませんが、まだです。2つを混ぜ合わせています。非クラスター化インデックスは一意である必要はなく、内部で一意化されていません。この点を十分に明確にしていません。回答で言うことはすべて、クラスター化インデックスにのみ適用されます。
スパゲッティ

@spaghettidba NCIは常に内部的に一意です。常にクエリプランの一部としてすべてのCIキーを出力できます。pastebin.com/vkGHpCsRを参照してください。NCIデータページには両方の列が含まれています。
usr

あなたがどこから来たのか分かります。複数のリーフが同じインデックスキーを共有できますが、クラスタリングキーは常にNCIに含まれます。それらは常に内部的に一意であると言えば十分でしょうか?私はそうは思いません。
スパゲッティ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.