Partager via


Spécifier les chemins d’accès et les indicateurs d’optimisation des index XML sélectifs

S’applique à : SQL Server Azure SQL Database Azure SQL Managed Instance

Cet article explique comment spécifier les chemins d'accès de nœud à indexer et les indicateurs d'optimisation pour l'indexation lorsque vous créez ou modifiez des index XML sélectifs.

Vous spécifiez les chemins d'accès de nœud et les indicateurs d'optimisation en même temps dans l'une des instructions suivantes :

Pour plus d’informations sur les index XML sélectifs, consultez Index XML sélectifs (SXI).

Présentation des types XQuery et SQL Server en XML non typé

Les index XML sélectifs prennent en charge deux systèmes de types : les types XQuery et les types SQL Server. Le chemin d'accès indexé peut être utilisé pour correspondre à une expression XQuery, ou pour correspondre au type de retour de la méthode value() de type de données xml.

  • Lorsqu'un chemin d'accès à indexer n'est pas annoté, ou est annoté avec le mot clé XQUERY, il correspond à une expression XQuery. Il existe deux variantes des chemins d'accès de nœud annotés XQUERY :

    • Si vous ne spécifiez pas le mot clé XQUERY et le type de données XQuery, des mappages par défaut sont utilisés. En général, les performances et le stockage ne sont pas optimaux.

    • Si vous spécifiez le mot clé XQUERY et le type de données XQuery, et éventuellement d'autres indicateurs d'optimisation, vous pouvez obtenir de meilleures performances et le stockage le plus efficace possible. Toutefois, une conversion peut échouer.

  • Lorsqu'un chemin d'accès à indexer est annoté avec le mot clé SQL, le chemin d'accès correspond au type de retour de la méthode value() de type de données xml. Spécifiez le type de données SQL Server approprié, qui est le type de retour attendue de la méthode value().

Il existe de légères variantes entre le système de type XML d'expressions XQuery et le système de type SQL Server appliqués à la méthode value() de type de données xml. Ces différences sont les suivantes :

  • Le système de type XQuery tient compte des espaces à droite. Par exemple, en fonction de la sémantique de type XQuery, les chaînes "abc" et "abc " SQL Server sont différentes, alors que dans SQL Server ces chaînes sont équivalentes.

  • Les types de données à virgule flottante XQuery prennent en charge les valeurs spéciales +/- zéro et +/- infini. Ces valeurs spéciales ne sont pas prises en charge dans les types de données à virgule flottante SQL Server.

Types XQuery en XML non typé

  • Les types XQuery correspondent aux expressions XQuery dans toutes les méthodes de type de données xml incluant la méthode value().

  • Les types XQuery prennent en charge ces indicateurs d'optimisation : node(), SINGLETON, DATA TYPE et MAXLENGTH.

Pour les expressions XQuery sur le XML non typé, vous pouvez choisir entre deux modes d'opération :

  • Mode de mappage par défaut. Dans ce mode, vous spécifiez uniquement le chemin d'accès lors de la création d'un index XML sélectif.

  • Mode de mappage défini par l’utilisateur. Dans ce mode, vous spécifiez le chemin d'accès et les indicateurs facultatifs d'optimisation.

Le mode de mappage par défaut utilise une option de stockage pessimiste qui est toujours sécurisée et générale. Il peut correspondre à n'importe quel type d'expression. Une limitation du mode de mappage par défaut est inférieure aux performances optimales, car un nombre accru de conversions d'exécution sont requis, et les index secondaires sont pas disponibles.

Voici un exemple d'index XML sélectif créé avec les mappages par défaut. Pour les trois chemins d’accès, le type de nœud par défaut (xs:untypedAtomic) et la cardinalité sont utilisés.

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

Le mode de mappage défini par l'utilisateur vous permet de spécifier un type et une cardinalité du nœud pour obtenir de meilleures performances. Toutefois, ces performances accrues sont obtenues au détriment de la sécurité, car une conversion peut échouer et en général seul le type spécifié est mis en correspondance avec l’index XML sélectif.

Les types XQuery pris en charge pour le XML non typé sont les suivants :

  • xs:boolean
  • xs:double
  • xs:string
  • xs:date
  • xs:time
  • xs:dateTime

Si le type n’est pas spécifié, le nœud est du type de données xs:untypedAtomic par défaut.

Vous pouvez optimiser l'index XML sélectif affiché de la manière suivante :

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.

Types SQL Server en XML non typé

  • Les types SQL Server correspondent à la valeur de retour de la méthode value().

  • Les types SQL Server prennent en charge l’indicateur d’optimisation suivant : SINGLETON.

Spécifier un type est obligatoire pour les chemins d'accès qui retournent des types SQL Server. Utilisez le même type SQL Server que vous utiliseriez dans la méthode value().

Considérez la requête suivante :

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

La requête spécifiée retourne une valeur du chemin d'accès /a/b/d compressé dans un type de données NVARCHAR(200). Ainsi, le type de données à spécifier pour le nœud est évident. Néanmoins, il n'existe aucun schéma pour spécifier la cardinalité du nœud en XML non typé. Pour spécifier que le nœud d apparaît au plus une fois sous son nœud parent b, créez un index XML sélectif qui utilise l'indicateur d'optimisation de SINGLETON comme suit :

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

Présentation de la prise en charge des index XML sélectifs pour le XML typé

Le XML typé de SQL Server est un schéma associé à un document XML donné. Ce schéma définit la structure globale du document et les types de nœuds. S'il existe un schéma, l'index XML sélectif applique la structure de schéma lorsque l'utilisateur promeut les chemins d'accès. Il est donc inutile de spécifier les types XQUERY pour les chemins d'accès.

Les index XML sélectifs prennent en charge les types XSD suivants :

  • 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

Lorsqu'un index XML sélectif est créé sur un document auquel un schéma est associé, la spécification d'un type XQuery lors de la création ou de la modification de l'index entraîne une erreur. L'utilisateur peut utiliser des annotations de type SQL dans le cadre de la promotion de chemin d'accès. Le type SQL doit être une conversion valide du type XSD défini dans le schéma, sinon une erreur est générée. Tous les types SQL disposant des performances adéquates dans le schéma XSD sont pris en charge, sauf les types date/heure.

Remarque

L'index sélectif est utilisé si le type spécifié dans la promotion de chemin d'accès d'index XML sélectif est identique à la valeur retournée par la méthode value().

Les indicateurs d'optimisation suivants peuvent être utilisés avec des documents XML typés :

  • indicateur d'optimisation node()

  • L'indicateur d'optimisation MAXLENGTH peut être utilisé avec types xs:string pour raccourcir la valeur indexée.

Pour plus d’informations sur les indicateurs d’optimisation, consultez Spécification des indicateurs d’optimisation.

Spécifier des chemins d’accès

Un index XML sélectif vous permet d'indexer uniquement un sous-ensemble de nœuds de données XML stockées en rapport avec les requêtes que vous comptez exécuter. Lorsque le sous-ensemble de nœuds appropriés est beaucoup plus petit que le nombre total de nœuds dans le document XML, l'index XML sélectif stocke uniquement les nœuds appropriés. Pour bénéficier d'un index XML sélectif, identifiez le sous-ensemble correct de nœuds à indexer.

Sélection des nœuds à indexer

Vous pouvez utiliser les deux principes suivants pour identifier le sous-ensemble correct de nœuds à ajouter à un index XML sélectif.

  1. Principe 1: pour évaluer une expression XQuery donnée, indexez tous les nœuds que vous devez examiner.

    • Indexez tous les nœuds dont l'existence ou la valeur est utilisée dans l'expression XQuery.

    • Indexez tous les nœuds de l'expression XQuery sur laquelle les prédicats XQuery sont appliqués.

    Considérez la requête suivante sur l’exemple de document XML dans cet article:

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

    Pour retourner des instances XML qui satisfont cette requête, un index XML sélectif doit examiner deux nœuds dans chaque instance XML :

    • Le nœud c, car sa valeur est utilisée dans l'expression XQuery.

    • Le nœud b, car un prédicat est appliqué sur le nœudb dans l'expression XQuery.

  2. Principe 2: pour obtenir de meilleures performances, indexez tous les nœuds requis pour évaluer une expression XQuery donnée. Si vous n'indexez que certains nœuds, l'index XML sélectif améliore l'évaluation des sous-expressions qui ne comprennent que les nœuds indexés.

Pour améliorer les performances de l'instruction SELECT ci-dessus, créez l'index XML sélectif suivant :

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

Indexation de chemins d'accès identiques

Vous ne pouvez pas promouvoir des chemins d'accès identiques de même type de données sous des noms de chemins d'accès différents. Par exemple, la requête suivante génère une erreur, car pathOne et pathTwo sont identiques :

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'
);

Toutefois, vous pouvez promouvoir des chemins d'accès de types de données différents avec des noms différents. Par exemple, la requête suivante est maintenant acceptable, car les types de données sont différents :

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'
);

Exemples

Voici quelques exemples supplémentaires de sélection des nœuds appropriés pour indexer des types XQuery différents.

Exemple 1

Voici une requête XQuery simple qui utilise la méthode exist() :

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

Le tableau suivant indique les nœuds qui doivent être indexés pour laisser cette requête utiliser les index XML sélectifs.

Nœd à inclure dans l'index Raison de l'indexation de ce nœud
/a/b/c/d/e/h L'existence du nœud h est évaluée dans la méthode exist().

Exemple 2

Voici une variation plus complexe de la requête XQuery précédente, avec un prédicat appliqué :

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

Le tableau suivant indique les nœuds qui doivent être indexés pour laisser cette requête utiliser les index XML sélectifs.

Nœd à inclure dans l'index Raison de l'indexation de ce nœud
/a/b/c/d/e Un prédicat est appliqué sur le nœud e.
/a/b/c/d/e/f La valeur du nœud f est évaluée au sein du prédicat.

Exemple 3

Voici une requête plus complexe avec une clause value() :

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

Le tableau suivant indique les nœuds qui doivent être indexés pour laisser cette requête utiliser les index XML sélectifs.

Nœd à inclure dans l'index Raison de l'indexation de ce nœud
/a/b/c/d/e Un prédicat est appliqué sur le nœud e.
/a/b/c/d/e/f La valeur du nœud f est évaluée au sein du prédicat.
/a/b/c/d/e/g La valeur du nœud g est retournée par la méthode value().

Exemple 4

Voici une requête qui utilise une clause FLWOR dans une clause exist(). (Le nom FLWOR provient des cinq clauses qui peuvent composer une expression XQuery FLWOR : FOR, LET, WHERE, ORDER BY et 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;

Le tableau suivant indique les nœuds qui doivent être indexés pour laisser cette requête utiliser les index XML sélectifs.

Nœd à inclure dans l'index Raison de l'indexation de ce nœud
/a/b/c/d/e L'existence du nœud e est évaluée dans la clause FLWOR.
/a/b/c/d/e/f La valeur du nœud f est évaluée dans la clause FLWOR.
/a/b/c/d/e/g L'existence du nœud g est évaluée par la méthode exist exist().

Spécification des indicateurs d’optimisation

Vous pouvez utiliser des indicateurs facultatifs d'optimisation pour spécifier des détails supplémentaires de mappage pour un nœud indexé par un index XML sélectif. Par exemple, vous pouvez spécifier le type de données et la cardinalité du nœud, ainsi que certaines informations sur la structure des données. Ces informations permettent un meilleur mappage. Elles entraînent également des améliorations des performances ou des économies en termes de stockage, ou les deux.

L'utilisation des indicateurs d'optimisation est facultative. Vous pouvez toujours accepter les mappages par défaut, qui sont fiables mais ne permettent pas des performances et un stockage optimaux.

Certains indicateurs d’optimisation (par exemple, l’indicateur SINGLETON) introduisent des contraintes sur vos données. Dans certains cas, des erreurs peuvent être générées lorsque ces contraintes ne sont pas satisfaites.

Avantages des indicateurs d'optimisation

Le tableau suivant identifie les indicateurs d'optimisation qui prennent en charge un stockage plus efficace ou de meilleures performances.

indicateur d'optimisation Stockage plus efficace performances améliorées
node() Oui Non
SINGLETON Non Oui
DATA TYPE Oui Oui
MAXLENGTH Oui Oui

Indicateurs d'optimisation et types de données

Vous pouvez indexer des nœuds en tant que types de données XQuery ou en tant que types de données SQL Server. Le tableau suivant illustre les indicateurs d'optimisation pris en charge avec chaque type de données.

indicateur d'optimisation Types de données XQuery Types de données SQL
node() Oui Non
SINGLETON Oui Oui
DATA TYPE Oui Non
MAXLENGTH Oui Non

Indicateur d'optimisation node()

S'applique à : types de données XQuery

Vous pouvez utiliser l'optimisation node() pour spécifier un nœud dont la valeur n'est pas requise pour évaluer la requête classique. Cet indicateur réduit les besoins de stockage lorsque la requête classique doit uniquement évaluer l'existence du nœud. (Par défaut, un index XML sélectif stocke la valeur de tous les nœuds promus, à l'exception des types de nœuds complexes.)

Prenons l’exemple suivant :

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

Pour utiliser un index XML sélectif pour évaluer cette requête, effectuez la promotion des nœuds b et c. Toutefois, étant donné que la valeur du nœud b n'est pas obligatoire, vous pouvez utiliser l'indicateur node() avec la syntaxe suivante :

`/a/b/ as node()

Si une requête requiert la valeur d'un nœud qui a été indexé avec l'indicateur node(), l'index XML sélectif ne peut pas être utilisé.

Indicateur d'optimisation SINGLETON

S'applique à : types de données XQuery ou

L'indicateur d'optimisation SINGLETON spécifie la cardinalité d'un nœud. Cet indicateur améliore les performances des requêtes, car il sait à l'avance qu'un nœud apparaît au plus une fois dans son parent ou ancêtre.

Examinez l’exemple de document XML dans cet article.

Pour utiliser un index XML sélectif pour interroger ce document, spécifiez l'indicateur SINGLETON du nœud d , car il apparaît au plus une fois dans son parent.

Si l'indicateur SINGLETON a été spécifié, mais un nœud apparaît plusieurs fois dans son parent ou ancêtre, une erreur est générée lorsque vous créez l'index (pour les données existantes) ou lorsque vous exécutez une requête (pour les nouvelles données).

Indicateur d'optimisation DATA TYPE

S'applique à : types de données XQuery

L'indicateur d'optimisation DATA TYPE vous permet de spécifier un type de données XQuery ou SQL Server du nœud indexé. Le type de données est utilisé pour la colonne dans la table de données de l'index XML sélectif qui correspond au nœud indexé.

Lors de la conversion d'une valeur existante dans le type de données spécifié échoue, l'opération d'insertion (dans l'index) réussit ; toutefois, une valeur NULL est insérée dans la table de données de l'index.

Indicateur d'optimisation MAXLENGTH

S'applique à : types de données XQuery

L'indicateur d'optimisation MAXLENGTH vous permet de limiter la longueur de données xs:string. MAXLENGTH n'est pas pertinente pour les types de données SQL Server étant donné que vous spécifiez la longueur lorsque vous spécifiez les types de dates VARCHAR ou NVARCHAR.

Lorsqu'une chaîne existante est plus longue que l'indicateur MAXLENGTH spécifié, l'insertion de cette valeur dans l'index échoue.

Document XML des exemples

Le document XML suivant est référencé dans les exemples de cet article:

<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>

Voir aussi