Задайте путь и указания по оптимизации для селективных XML-индексов

В данном разделе описывается настройка путей узла для индексирования и задание указаний по оптимизации для индексирования при создании или изменении селективных XML-индексов.

Пути узла и указания по оптимизации задаются одновременно в одной из следующих инструкций:

Дополнительные сведения о селективных XML-индексах см. в разделе Выборочный XML-индекс (SXI).

В этом разделе

  • Основные сведения о типах Xquery и SQL Server в нетипизированном XML

  • Основные сведения о поддержке селективных XML-индексов для типизированных XML-документов

  • Указание путей

  • Задание указаний по оптимизации

  • Образец XML-документа для примеров

Основные сведения о типах Xquery и SQL Server в нетипизированном XML

Селективные XML-индексы поддерживают две системы типов. Типы XQuery и типы SQL Server. Индексированный путь можно использовать для сопоставления с выражением Xquery или с возвращаемым типом метода value() типа данных XML.

  • Если путь для индексирования не снабжен заметками или ключевым словом XQUERY, путь будет сопоставляться с выражением Xquery. Есть две вариации путей узла, снабженных ключевым словом XQUERY.

    • Если ключевое слово XQUERY и тип данных XQuery не указаны, будут использоваться сопоставления по умолчанию. Обычно производительность и хранение не являются оптимальными.

    • Если было указано ключевое слово XQUERY и тип данных Xquery, а также другие указания по оптимизации (необязательно), вы можете достичь наилучшей возможной производительности и наиболее эффективного хранения. Однако приведение может завершиться ошибкой.

  • Если путь для индексирования снабжен ключевым словом SQL, путь сопоставляется с возвращаемым типом метода value() типа данных XML. Укажите подходящий тип данных SQL Server, то есть возвращаемый тип, который ожидается от метода value().

Есть малозаметные различия между системой типов XML выражений Xquery и системой типов SQL Server, примененных к методу value() типа данных XML. Различия следующие:

  • Система типов Xquery учитывает конечные пробелы. Например, в соответствии с семантикой типов Xquery строки «abc» и «abc » не равны, тогда как в SQL Server эти строки равны.

  • Типы данных с плавающей запятой Xquery поддерживают специальные значения +/- нуль и +/- бесконечность. Эти особые значения не поддерживаются в типах данных с плавающей запятой SQL Server.

Типы Xquery в нетипизированном XML

  • Типы XQuery сопоставляются с выражениями XQuery во всех методах типа данных XML, включая метод value().

  • Типы Xquery поддерживают следующие указания по оптимизации: node(), SINGLETON, DATA TYPE и MAXLENGTH.

В выражениях Xquery с нетипизированным XML вы можете выбрать между двумя режимами работы.

  • Режим сопоставления по умолчанию. В этом режиме при создании селективного XML-индекса указывается только путь.

  • Определяемый пользователем режим сопоставления. В этом режиме указывается как путь, так и необязательные указания по оптимизации.

Режим сопоставления по умолчанию использует консервативный режим хранения, который всегда безопасен и универсален. Он может быть сопоставлен с любым типом выражения. Ограничением режима сопоставления по умолчанию является неоптимальная производительность, поскольку требуется увеличение количества приведений среды выполнения. Также будут недоступны вторичные индексы.

Ниже приведен пример селективного XML-индекса, созданного с сопоставлениями по умолчанию. Для всех трех методов используется тип узла и количество элементов по умолчанию (xs:untypedAtomic).

CREATE SELECTIVE XML INDEX example_sxi_UX_default
ON Tbl(xmlcol)
FOR
(
mypath01 =  '/a/b',
mypath02 = '/a/b/c',
mypath03 = '/a/b/d'
)

Определяемый пользователем режим сопоставления позволяет указать тип и количество элементов для узла, чтобы получить более высокую производительность. Однако это повышение производительности достигается за счет снижения безопасности (поскольку приведения могут завершаться с ошибками) и универсальности (поскольку с селективным XML-индексом сопоставляется только заданный тип).

Для нетипизированного XML поддерживаются следующие типы Xquery:

  • xs:boolean

  • xs:double

  • xs:string

  • xs:date

  • xs:time

  • xs:dateTime

Если тип не указан, предполагается, что узел имеет тип данных xs:untypedAtomic.

Отображенный селективный XML-индекс вы можете оптимизировать следующим образом:

CREATE SELECTIVE XML INDEX example_sxi_UX_optimized
ON Tbl(xmlcol)
FOR
(
mypath= '/a/b' as XQUERY 'node()',
pathX = '/a/b/c' as XQUERY 'xs:double' SINGLETON,
pathY = '/a/b/d' as XQUERY 'xs:string' MAXLENGTH(200) SINGLETON
)
-- mypath – Only the node value is needed; storage is saved.
-- pathX – Performance is improved; secondary indexes are possible.
-- pathY - Performance is improved; secondary indexes are possible; storage is saved.

Типы SQL Server в нетипизированном XML

  • Типы SQL Server соответствуют возвращаемому значению метода value().

  • Типы SQL Server, которые поддерживают это указание оптимизации: SINGLETON.

Указание типа обязательно для путей, возвращающих типы SQL Server. Необходимо использовать тот же тип SQL Server, который бы использовался в методе value().

Обратите внимание на следующий запрос:

SELECT T.record,
    T.xmldata.value('(/a/b/d)[1]', 'NVARCHAR(200)')
FROM myXMLTable T

Указанный запрос возвращает значение из пути /a/b/d, упакованного в тип данных NVARCHAR(200), поэтому тип данных, указываемый для узла, является очевидным. Однако нет схемы, в которой можно было бы указать количество элементов узла в нетипизированном XML. Чтобы указать, что узел d должен встречаться не более одного раза в родительском узле b, создайте селективный XML-индекс, в котором подсказка оптимизации SINGLETON используется следующим образом:

CREATE SELECTIVE XML INDEX example_sxi_US
ON Tbl(xmlcol)
FOR
(
node1223 = '/a/b/d' as SQL NVARCHAR(200) SINGLETON
)

[В начало]

Основные сведения о поддержке селективных XML-индексов для типизированного XML

Типизированный XML в SQL Server — это схема, связанная с данным XML-документом. Схема определяет общую структуру документа и типы узлов. Если схема существует, то селективный XML-индекс применяет структуру схемы, когда пользователь повышает пути, поэтому нет необходимости указывать типы XQUERY для путей.

Селективные XML-индексы поддерживают следующие типы XSD:

  • xs:anyUri

  • xs:boolean

  • xs:date

  • xs:dateTime

  • xs:day

  • xs:decimal

  • xs:double

  • xs:float

  • xs:int

  • xs:integer

  • xs:language

  • xs:long

  • xs:name

  • xs:NCName

  • xs:negativeInteger

  • xs:nmtoken

  • xs:nonNegativeInteger

  • xs:nonPositiveInteger

  • xs:positiveInteger

  • xs:qname

  • xs:short

  • xs:string

  • xs:time

  • xs:token

  • xs:unsignedByte

  • xs:unsignedInt

  • xs:unsignedLong

  • xs:unsignedShort

Если селективный XML-индекс создается для документа, имеющего связанную с ним схему, то при указании типа XQUERY при создании или изменении индекса будет возвращена ошибка. Пользователь может использовать заметки типов SQL в части повышения пути. Тип SQL должен быть допустимым преобразованием из типа XSD, определенного в схеме, иначе будет выдана ошибка. Поддерживаются все типы SQL, имеющие адекватное представление в XSD, за исключением типов данных даты-времени.

ПримечаниеПримечание

Селективный индекс используется, если в повышении пути селективного XML-индекса указан тот же тип, что и в возвращаемом значении метода value().

Следующие указания оптимизации можно использовать с типизированными XML-документами.

  • Указание по оптимизации node().

  • Указание оптимизации MAXLENGTH можно использовать с типами xs:string, чтобы сократить индексируемое значение.

Дополнительные сведения об указаниях по оптимизации см. в разделе Задание указаний по оптимизации.

Указание путей

Селективный XML-индекс позволяет индексировать только подмножество узлов из сохраненных XML-данных, значимое для запросов, которые планируется выполнять. Когда подмножество значимых узлов намного меньше, чем общее количество узлов в XML-документе, селективный XML-индекс сохраняет только значимые узлы. Для эффективного использования селективного XML-индекса необходимо определить нужное подмножество узлов для индексирования.

Выбор узлов для индексирования

Следующие два простых принципа позволяют определить нужное подмножество узлов, которые необходимо добавить в селективный XML-индекс.

  1. Принцип 1. Чтобы оценить заданное выражение Xquery, необходимо проиндексировать все узлы, подлежащие изучению.

    • Индексируйте все узлы, существование или значения которых используются в выражении XQuery.

    • Индексируйте все узлы в выражении XQuery, к которым применяются предикаты XQuery.

    Рассмотрим следующий простой запрос к образцу XML-документа в данном разделе.

    SELECT T.record FROM myXMLTable T
    WHERE T.xmldata.exist('/a/b[./c = "43"]') = 1
    

    Для возвращения экземпляров XML, которые удовлетворяют запросу, селективному XML-индексу необходимо просматривать 2 узла в каждом из экземпляров XML.

    • Узел c, так как его значение используется в выражении XQuery.

    • Узел b, поскольку предикат применяется на узел b в выражении XQuery.

  2. Принцип 2. Для достижения наилучшей производительности рекомендуется индексировать все узлы, необходимые для вычисления заданного выражения XQuery. Если индексируются только некоторые узлы, селективный XML-индекс улучшает оценку вложенных выражений, содержащих только индексированные узлы.

Для улучшения производительности инструкции SELECT, описанной выше, вы можете создать следующий селективный XML-индекс.

CREATE SELECTIVE XML INDEX simple_sxi
ON Tbl(xmlcol)
FOR
(
    path123 =  '/a/b',
    path124 =  '/a/b/c'
)

Индексирование одинаковых путей

Невозможно повысить уровень одинаковых путей в качестве того же типа данных с другими именами пути. Например, следующий запрос формирует ошибку, поскольку пути pathOne и pathTwo идентичны:

CREATE SELECTIVE INDEX test_simple_sxi ON T1(xmlCol)
FOR
(
    pathOne = 'book/authors/authorID' AS XQUERY 'xs:string',
    pathTwo = 'book/authors/authorID' AS XQUERY 'xs:string'
)

Однако вы можете повысить уровень одинаковых путей в качестве различных типов данных с разными именами. Например, следующий запрос теперь является допустимым, поскольку типы данных отличаются:

CREATE SELECTIVE INDEX test_simple_sxi ON T1(xmlCol)
FOR
(
    pathOne = 'book/authors/authorID' AS XQUERY 'xs:double',
    pathTwo = 'book/authors/authorID' AS XQUERY 'xs:string'
)

Примеры

Ниже приведены дополнительные примеры выбора правильных узлов для индексации для различных типов XQuery.

Пример 1

Вот простой запрос Xquery, в котором используется метод exist():

SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('/a/b/c/d/e/h') = 1

В следующей таблице показаны узлы, которые должны быть индексированы для того, чтобы данный запрос мог использовать селективный XML-индекс.

Узел, который необходимо включить в индекс

Причина для индексирования этого узла

/a/b/c/d/e/h

Наличие узла h вычисляется в методе exist().

Пример 2

Вот более сложный вариант предыдущего запроса XQuery с примененным предикатом:

SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('/a/b/c/d/e[./f = "SQL"]') = 1

В следующей таблице показаны узлы, которые должны быть индексированы для того, чтобы данный запрос мог использовать селективный XML-индекс.

Узел, который необходимо включить в индекс

Причина для индексирования этого узла

/a/b/c/d/e

Предикат применяется для узла e.

/a/b/c/d/e/f

Значение узла f вычисляется внутри предиката.

Пример 3

Вот более сложный запрос с предложением value():

SELECT T.record,
    T.xmldata.value('(/a/b/c/d/e[./f = "SQL"]/g)[1]', 'nvarchar(100)')
FROM myXMLTable T

В следующей таблице показаны узлы, которые должны быть индексированы для того, чтобы данный запрос мог использовать селективный XML-индекс.

Узел, который необходимо включить в индекс

Причина для индексирования этого узла

/a/b/c/d/e

Предикат применяется для узла e.

/a/b/c/d/e/f

Значение узла f вычисляется внутри предиката.

/a/b/c/d/e/g

Значение узла g возвращается методом value().

Пример 4

Вот запрос, в котором предложение FLWOR используется внутри предложения exist(). (Имя FLWOR образуется из 5 предложений, которые могут составлять выражение FLWOR в Xquery: for, let, where, order by и return.)

SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('
  For $x in /a/b/c/d/e
  Where $x/f = "SQL"
  Return $x/g
') = 1

В следующей таблице показаны узлы, которые должны быть индексированы для того, чтобы данный запрос мог использовать селективный XML-индекс.

Узел, который необходимо включить в индекс

Причина для индексирования этого узла

/a/b/c/d/e

Наличие узла e вычисляется в предложении FLWOR.

/a/b/c/d/e/f

Значение узла f вычисляется в предложении FLWOR.

/a/b/c/d/e/g

Наличие узла g вычисляется методом exist().

[В начало]

Задание указаний по оптимизации

Необязательные указания оптимизации можно использовать для указания дополнительных подробностей сопоставления для узла, индексированного селективным XML-индексом. Например, вы можете указать тип данных, количество элементов узла, а также некоторые сведения о структуре данных. Эта дополнительная информация поддерживает более эффективное сопоставление. Она также позволяет получить улучшение производительности, эффективности хранения или и того и другого.

Использование указаний оптимизации необязательно. Всегда вы можете принять сопоставления по умолчанию, которые являются надежными, но не обеспечивают оптимальную производительность и эффективность хранения.

Некоторые указания по оптимизации (например, указание SINGLETON) накладывают ограничения на данные. В некоторых случаях, когда эти ограничения не выполняются, могут возникать ошибки.

Преимущества использования указаний оптимизации

В следующей таблице приведены указания по оптимизации, которые поддерживают более эффективное хранение или улучшение в производительности.

Указание по оптимизации

Более эффективное хранение

Повышенная производительность

node()

Да

Нет

SINGLETON

Нет

Да

DATA TYPE

Да

Да

MAXLENGTH

Да

Да

Указания по оптимизации и типы данных

Узлы вы можете индексировать как типы данных XQuery или как типы данных SQL Server. В следующей таблице показано, какие указания оптимизации поддерживаются для каждого типа данных.

Указание по оптимизации

Типы данных XQuery

Типы данных SQL

node()

Да

Нет

SINGLETON

Да

Да

DATA TYPE

Да

Нет

MAXLENGTH

Да

Нет

Указание по оптимизации node()

Область применения: Типы данных XQuery

Вы можете использовать оптимизацию node(), чтобы указать узел, значение которого не требуется для вычисления обычного запроса. Это указание снижает требования к хранилищу, поскольку обычному запросу необходимо вычислить только существование узла. (По умолчанию селективный XML-индекс хранит значения всех повышенных узлов, за исключением сложных типов узлов.)

Рассмотрим следующий пример.

SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('/a/b[./c=5]') = 1

Для использования селективного XML-индекса для оценки этого запроса повысьте узлы b и c. Однако, поскольку значение узла b не требуется, вы можете использовать указание node() со следующим синтаксисом:

/a/b/ as node()

Если для запроса необходимо значение узла, который был индексирован с указанием node(), селективный XML-индекс использовать нельзя.

Указание по оптимизации SINGLETON

Область применения: Типы данных SQL Server или XQuery

Указание по оптимизации SINGLETON указывает количество элементов узла. Это указание повышает производительность запросов, поскольку известно, что узел отображается максимум один раз в его родителе или предке.

Рассмотрим образец XML-документа в этом разделе.

Для использования селективного XML-индекса в запросе к этому документу вы можете задать указание SINGLETON для узла d, поскольку он встречается максимум один раз в его родительском элементе.

Если было задано указание SINGLETON, а узел встречается более одного раза в его родителе или предке, то при создании индекса (для существующих данных) или при выполнении запроса (для новых данных) возникнет ошибка.

Указание по оптимизации DATA TYPE

Область применения: Типы данных XQuery

Указание по оптимизации DATA TYPE позволяет задать тип данных XQuery или SQL Server для индексированного узла. Тип данных используется для столбца в таблице данных селективного XML-индекса, соответствующего индексированному узлу.

Если приведение существующего значения в указанный тип данных завершается ошибкой, операция вставки (в индекс) не завершается ошибкой, однако в таблицу данных индекса вставляется значение NULL.

Указание по оптимизации MAXLENGTH

Область применения: Типы данных XQuery

Указание по оптимизации MAXLENGTH позволяет ограничить длину данных xs:string. Указание MAXLENGTH несущественно для типов данных SQL Server, поскольку длина указывается при указании типов данных VARCHAR или NVARCHAR.

Если существующая строка длиннее значения MAXLENGTH, вставка этого значения в индекс завершается с ошибкой.

[В начало]

Образец XML-документа для примеров

Следующий образец XML-документа указывается в примерах этого раздела.

<a>
    <b>
         <c atc="aa">10</c>
         <c atc="bb">15</c>
         <d atd1="dd" atd2="ddd">md </d>
    </b>
     <b>
        <c></c>
        <c atc="">117</c>
     </b>
</a>

[В начало]

См. также

Основные понятия

Выборочный XML-индекс (SXI)

Создание, изменение и удаление селективных XML-индексов