2010-01-11 4 views
4

Это искажает меня какое-то время, и я надеюсь, что один из экспертов SQL Server может пролить свет на него.Как работает индекс для SQL User-Defined Type (UDT)?

Возникает вопрос:

Когда индекс столбца 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 имеет особое понимание и автоматически изменяет план выполнения, если он находит определенную комбинацию элементов запроса и индексов? Или тип CLR SqlHierarchyID просто определяет специальные атрибуты/методы (аналогично тому, как IsDeterministic работает для постоянных вычисляемых столбцов), которые понимаются движком SQL Server?

Возможно, я не могу найти информацию об этом. Все, что мне удалось найти, - это абзац, в котором указано, что свойство IsByteOrdered делает такие вещи, как индексы, и проверяет ограничения, гарантируя одно уникальное представление для каждого экземпляра; в то время как это несколько интересно, он не объясняет, как SQL Server может выполнить искать с определенными методами экземпляра.

Итак, вопрос снова - как работают индексы для типов типа hierarchyid, и можно ли получить такое же поведение в новом UDT?

ответ

3

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

Итак ... Управление Предком эффективно, как использование оператора LIKE с началом строки. Это не изменяет порядок, и вы все равно можете уйти с вещами.

+0

«LEFT» и «CAST» становятся доступными в SQL Server 2008? У меня только 2005 на моей домашней машине, чтобы проверить, и они определенно вынуждают сканирование индекса здесь. Я проверю это на работе завтра, это будет интересно, если это правда. – Aaronaught

+0

CAST в некоторых ситуациях, даже в SQL 2005. CRAVE LART все еще нет, но LIKE - это когда подстановочный знак находится в конце, что по существу обеспечивает функциональность LEFT. –

+0

Я отредактирую ответ, чтобы уточнить, что я имею в виду «Левый» –

2

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

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

Смежные вопросы