Указание путей и подсказок оптимизации для выборочных XML-индексов
Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure
В этой статье описывается, как указать пути узлов для индексирования и оптимизации при создании или изменении выборочных XML-индексов.
Пути узла и указания по оптимизации задаются одновременно в одной из следующих инструкций:
В предложении FOR инструкции CREATE. Дополнительные сведения см. в разделе CREATE SELECTIVE XML INDEX (Transact-SQL).
В предложении ADD инструкции ALTER. Дополнительные сведения см. в разделе ALTER INDEX (выборочные 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. Чтобы оценить заданное выражение 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. Для достижения наилучшей производительности проиндексируйте все узлы, необходимые для вычисления заданного выражения 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 | No | Да |
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
Область применения: типы данных 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>