これはしばらくの間私を悩ませてきました、そして私はSQLServerの専門家の1人がそれにいくらかの光を当てることができることを望んでいます。
質問は:
UDT(CLRタイプ)を含むSQL Server列にインデックスを付ける場合、SQL Serverは、特定のクエリに対して実行するインデックス操作をどのように決定しますか?
具体的にはhierarchyid
(AKA SqlHierarchyID
)タイプを考えています。マイクロソフトが推奨する方法、および私が使用する方法は次のとおりです。
列自体にインデックスを作成します
hierarchyid
(これを呼び出しましょうID
)。これにより、深さ優先探索が可能になり、を記述したときにWHERE ID.IsDescendantOf(@ParentID) = 1
インデックスシークを実行できるようになります。永続化された計算
Level
列を作成し、にインデックスを作成します(Level, ID)
。これにより、幅優先探索が可能になり、を記述したときにWHERE ID.GetAncestor(1) = @ParentID
、この式に対して(2番目のインデックスで)インデックスシークを実行できるようになります。
しかし、私が理解していないのは、これがどのように可能であるかということです。 これは通常のクエリプランのルールに違反しているようです。呼び出しは引数GetAncestor
にIsDescendantOf
できないように見えるため、完全なインデックススキャンが実行されるはずですが、そうではありません。明らかに不満を言っているわけではありませんが、この機能を自分のUDTで複製できるかどうかを理解しようとしています。
hierarchyid
SQL Serverが特別に認識し、クエリ要素とインデックスの特定の組み合わせが見つかった場合に実行プランを自動的に変更する、単なる「魔法の」タイプですか?または、CLR型は、SQL Serverエンジンによって理解されるSqlHierarchyID
特別な属性/メソッド(永続化された計算列の動作と同様)を単純に定義しますか?IsDeterministic
これに関する情報が見つからないようです。私が見つけたのは、IsByteOrdered
インスタンスごとに1つの一意の表現を保証することで、プロパティがインデックスやチェック制約などを可能にすることを示す段落だけです。これはやや興味深いものですが、SQLServerが特定のインスタンスメソッドを使用してシークを実行する方法については説明していません。
では、もう一度質問します。インデックス操作は、のようなタイプに対してどのように機能しますhierarchyid
か。また、新しいUDTで同じ動作を実現することは可能ですか。