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

Применяется к:SQL ServerAzure SQL DatabaseAzure, управляемому экземпляру SQL Azure

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

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

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

Общие сведения о типах 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() Да No
SINGLETON No Да
DATA TYPE Да Да
MAXLENGTH Да Да

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

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

Указание по оптимизации Типы данных XQuery Типы данных SQL
node() Да No
SINGLETON Да Да
DATA TYPE Да No
MAXLENGTH Да No

Указание по оптимизации 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

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

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

Рассмотрим пример XML-документа в этой статье.

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

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

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

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

Указание оптимизации ТИПА ДАННЫХ позволяет указать 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>

См. также