Как работает индекс для пользовательского типа SQL (UDT)? - PullRequest
4 голосов
/ 11 января 2010

Меня это некоторое время беспокоило, и я надеюсь, что один из экспертов по 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?

Ответы [ 2 ]

4 голосов
/ 22 января 2010

Команда оптимизатора запросов пытается обработать сценарии, которые не меняют порядок вещей.Например, cast(someDateTime as date) все еще может быть sargable.Я надеюсь, что со временем они исправят кучу старых, таких как dateadd / datediff с константой.

Итак ... обработка Ancestor по сути аналогична использованию оператора LIKE сстрока.Это не меняет порядок, и вы все равно можете сойти с рук.

2 голосов
/ 24 февраля 2010

Вы правы - HierarchyId и Geometry / Geography оба являются «магическими» типами, которые оптимизатор запросов может распознавать и переписывать планы для создания оптимизированных запросов - это не так просто, как просто распознавать операторы sargable. Нет способа симулировать эквивалентное поведение с другими UDT.

Для HierarchyId двоичная сериализация типа является специальной для представления иерархической структуры в двоичном упорядоченном виде. Он аналогичен механизму, используемому типом SQL Xml, и описан в исследовательской работе ORDPATHs: метки XML-узла, удобные для вставки . Таким образом, хотя правила QO для перевода запросов, использующих IsDescendant и GetAncestor, являются особыми, фактический базовый индекс является регулярным реляционным индексом для данных двоичной иерархии, и вы можете добиться того же поведения, если вы захотите написать свои оригинальные запросы для выполнения поиска диапазона вместо вызова простого метода.

...