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

S’applique à :SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Cet article explique comment spécifier des chemins d’accès de nœud à des indicateurs d’indexation et d’optimisation 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).

Comprendre les types XQuery et SQL Server dans xml non typé

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

  • Lorsqu’un chemin d’accès à l’index n’est pas annoté ou est annoté avec le mot clé XQUERY, le chemin 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, les mappages par défaut sont utilisés. En règle générale, 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 à l’index est annoté avec le mot clé SQL, le chemin correspond au type de retour de la value() méthode du type de données xml . Spécifiez le type de données SQL Server approprié, qui est le type de retour attendu de la value() méthode.

Il existe des différences subtiles entre le système de type XML des expressions XQuery et le système de type SQL Server appliqué à la value() méthode du type de données xml . Ces différences sont les suivantes :

  • Le système de type XQuery tient compte des espaces à droite. Par exemple, selon la sémantique de type XQuery, les chaînes « abc » et « abc » ne sont pas égales, tandis que dans SQL Server, ces chaînes sont égales.

  • 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 dans xml non typé

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

  • 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 conservatrice, 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 casts d’exécution sont requis et les index secondaires ne sont pas disponibles.

Voici un exemple d’index XML sélectif créé avec des 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 supposé être du type de xs:untypedAtomic données.

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 dans xml non typé

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

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

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

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. Toutefois, 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
);

Comprendre la prise en charge sélective de l’index XML typé

Le code XML typé dans 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. Si un schéma existe, l’index XML sélectif applique la structure de schéma lorsque l’utilisateur promeut les chemins. Il n’est donc pas nécessaire 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 associé à un schéma, en spécifiant un type XQuery lors de la création de l’index ou en modifiant 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.

Note

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

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

  • node() indicateur d’optimisation.

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

Choisir les 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 indexez uniquement certains des nœuds, l’index XML sélectif améliore l’évaluation des sous-expressions qui incluent uniquement des 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'
);

Chemins identiques d’index

Vous ne pouvez pas promouvoir des chemins identiques comme le même type de données sous différents noms de chemins d’accès. 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'
);

Examples

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

Exemple 1

Voici un XQuery simple qui utilise la exist() méthode :

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 exist() méthode.

Exemple 2

Voici une variante plus complexe du XQuery précédent, 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 value() clause :

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 value() méthode.

Exemple 4

Voici une requête qui utilise une clause FLWOR à l’intérieur d’une exist() clause. (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 exist() méthode.

Spécifier 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, tels que 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 remplies.

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 nécessaire 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 requise, vous pouvez utiliser l’indicateur avec la node() syntaxe suivante :

`/a/b/ as node()

Si une requête nécessite 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 SQL Server

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

Considérez 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 pour le 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 sur le type de données spécifié échoue, l’opération d’insertion (dans l’index) n’échoue pas ; 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 pertinent pour les types de données SQL Server, car 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.

Exemple de document XML pour obtenir des exemples

L’exemple de 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