Меня это некоторое время беспокоило, и я надеюсь, что один из экспертов по SQL Server сможет пролить свет на это.
Вопрос:
Когда вы индексируете столбец SQL Server, содержащий UDT (тип CLR), как SQL Server определяет, какую операцию индексации выполнить для данного запроса?
В частности, я имею в виду тип hierarchyid
(AKA SqlHierarchyID
). Microsoft рекомендует вам использовать его - и то, как я его использую, - это:
Создать индекс для самого столбца hierarchyid
(назовем его ID
). Это позволяет осуществлять поиск в глубину, поэтому, когда вы пишете WHERE ID.IsDescendantOf(@ParentID) = 1
, он может выполнять поиск по индексу.
Создайте постоянный вычисляемый столбец Level
и создайте индекс для (Level, ID)
. Это позволяет осуществлять поиск в ширину, поэтому, когда вы пишете WHERE ID.GetAncestor(1) = @ParentID
, он может выполнить поиск по индексу (по второму индексу) для этого выражения.
Но я не понимаю, как это возможно? Кажется, что он нарушает обычные правила плана запросов - вызовы GetAncestor
и IsDescendantOf
не кажутся раздражительными, так что должно привести к полному сканированию индекса, но это не так. Не то чтобы я жалуюсь, очевидно, но я пытаюсь понять, возможно ли воспроизвести эту функцию на моих собственных UDT.
Является ли hierarchyid
просто «магическим» типом, о котором SQL Server особенно осведомлен, и автоматически меняет план выполнения, если находит определенную комбинацию элементов запроса и индексов? Или тип SqlHierarchyID
CLR просто определяет специальные атрибуты / методы (аналогично тому, как IsDeterministic
работает для постоянных вычисляемых столбцов), понятные механизму SQL Server?
Не могу найти информацию об этом. Все, что мне удалось найти, - это параграф, в котором говорится, что свойство IsByteOrdered
делает возможными такие вещи, как индексы и проверки ограничений, гарантируя одно уникальное представление для каждого экземпляра; хотя это несколько интересно, но не объясняет, как SQL Server может выполнять поиск с определенными методами экземпляра.
Итак, снова вопрос - как операции с индексами работают для таких типов, как hierarchyid
, и возможно ли получить такое же поведение в новом UDT?