Partager via


Index XML secondaires

Afin d'améliorer les performances lors des recherches, vous pouvez créer des index XML secondaires. Un index XML primaire doit être défini au préalable avant de pouvoir créer des index secondaires. Il en existe trois types différents :

  • les index XML secondaires de type PATH (s'appuyant sur le chemin d'accès) ;

  • les index XML secondaires de type VALUE (utilisant la valeur comme critère de recherche) ;

  • les index XML secondaires de type PROPERTY (pour rechercher des données d'après leurs propriétés).

Voici quelques consignes pour vous aider à créer un ou plusieurs index secondaires :

  • Si votre charge de travail utilise souvent des expressions de chemin sur les colonnes XML, l'index secondaire PATH a toutes les chances de l'accélérer. C'est ce que vous pouvez constater le plus souvent en cas d'utilisation de la méthode exist() sur des colonnes XML dans la clause WHERE de Transact-SQL.

  • Si votre charge de travail récupère plusieurs valeurs d'instances XML individuelles en utilisant des expressions de chemin, la mise en cluster des chemins pour chaque instance XML dans l'index PROPERTY peut s'avérer fort utile. Ce scénario se produit généralement avec un sac de propriétés où les propriétés d'un objet sont récupérées et la valeur de sa clé primaire est connue.

  • Si votre charge de travail implique le lancement de requêtes sur des valeurs d'instances XML pour lesquelles vous ne connaissez pas les noms d'élément ou d'attribut, vous aurez peut-être intérêt à créer l'index VALUE. C'est généralement ce qui se produit en cas de recherches d'axes descendants telles que //author[last-name="Howard"], où les éléments <author> peuvent se trouver à tout niveau de la hiérarchie. Cela se rencontre aussi dans les requêtes à caractères génériques telles que /book [@* = "novel"], où la requête recherche les éléments <book> ayant des attributs de valeur "novel".

Index XML secondaire de type PATH

Si vos requêtes précisent habituellement les expressions de chemin d'accès sur les colonnes de type xml, un index secondaire de type PATH peut s'avérer à même d'accélérer la recherche. Comme nous l'avons vu précédemment, l'index primaire est des plus utiles pour les requêtes indiquant la méthode exist() dans leur clause WHERE. Si vous ajoutez à présent un index secondaire de type PATH, il se peut que vous amélioriez encore la rapidité de la recherche lancée par de telles requêtes.

Bien qu'un index XML primaire évite de fragmenter les objets blob XML à l'exécution, il peut ne pas offrir les meilleurs temps de réponse pour les requêtes s'appuyant sur des expressions de chemin d'accès. Une recherche, lancée sur toutes les lignes constituant l'index XML primaire correspondant à un objet blob XML et s'opérant de façon séquentielle pour des instances XML volumineuses, peut s'avérer des plus lentes. Dans ce cas, un index secondaire construit sur les valeurs de chemin d'accès et sur celles des nœuds de l'index primaire peut accélérer de façon significative la recherche sur l'index. Dans le cas d'un index XML secondaire de type PATH, les valeurs de chemin d'accès et des nœuds correspondent à des colonnes clés permettant donc des recherches plus efficaces si ces dernières portent sur le chemin d'accès. Il se peut que l'optimiseur de requête utilise l'index de type PATH dans des expressions telles que celles mentionnées ci-dessous :

  • /root/Location, n'indiquant que son chemin d'accès ;

- ou -

  • /root/Location/@LocationID[.="10"], où le chemin et la valeur du nœud sont précisés.

La requête suivante illustre un cas de figure où l'index de type PATH s'avère particulièrement utile :

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS "PD")

SELECT CatalogDescription.query('
  /PD:ProductDescription/PD:Summary
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.exist ('/PD:ProductDescription/@ProductModelID[.="19"]') = 1

Dans la requête, l'expression de chemin d'accès /PD:ProductDescription/@ProductModelID et sa valeur "19" se trouvant dans la méthode exist() correspondent aux champs de clé définis pour l'index de type PATH. Des recherches directes portant sur l'index PATH peuvent s'effectuer et offrir ainsi de meilleures performances que dans le cas d'une recherche séquentielle portant sur les valeurs de chemin d'accès de l'index primaire.

Index XML secondaire de type VALUE

Si des requêtes s'appuient sur les valeurs pour ses résultats, par exemple /Root/ProductDescription/@*[. = "Mountain Bike"] ou //ProductDescription[@Name = "Mountain Bike"], et que le chemin n'est pas entièrement précisé ou qu'il contient un caractère générique, vous pourriez obtenir des résultats plus rapidement en construisant un index XML secondaire sur les valeurs des nœuds de l'index XML primaire.

Les colonnes clés (correspondant aux valeurs de nœud et aux chemins d'accès) de l'index de type VALUE sont tirées de l'index XML primaire. Si vous devez lancer des requêtes sur des valeurs provenant d'instances XML sans connaître le nom des éléments ou des attributs contenant les valeurs, il se peut que l'index de type VALUE vous soit particulièrement utile. Par exemple, l'expression suivante tire parti de l'utilisation d'un index de type VALUE :

  • //author[LastName="someName"], où vous connaissez la valeur de l'élément <LastName>, mais où le parent <author> peut se placer n'importe où.

  • /book[@* = "someValue"], où la requête recherche l'élément <book> dont un attribut possède la valeur "someValue".

La requête suivante renvoie ContactID à partir de la table Contact. La clause WHERE indique un filtre permettant de rechercher des valeurs dans la colonne AdditionalContactInfo de type xml. L'ID des contacts n'est renvoyé que si l'objet blob XML relatif aux informations complémentaires sur les contacts correspondants contient un numéro de téléphone spécifique. Puisque l'élément <telephoneNumber> peut apparaître n'importe où dans le document XML, l'expression du chemin d'accès indique l'axe descendant-or-self.

WITH XMLNAMESPACES (
  'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo' AS CI,
  'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes' AS ACT)

SELECT ContactID 
FROM   Person.Contact
WHERE  AdditionalContactInfo.exist('//ACT:telephoneNumber/ACT:number[.="111-111-1111"]') = 1

Dans ce cas, nous connaissons donc la valeur de recherche correspondant à <number> mais elle peut se trouver n'importe où dans l'instance XML en tant qu'enfant de l'élément <telephoneNumber>. Ce type de requête pourrait être plus efficace grâce à la recherche d'une valeur précise dans les index.

Index secondaire de type PROPERTY

Les requêtes chargées d'extraire plusieurs valeurs d'instances XML distinctes peuvent bénéficier de l'utilisation d'un index de type PROPERTY. Un scénario type de cette utilisation s'illustre lorsque vous récupérez les propriétés d'objets par le biais de la méthode value() de type xml et que la valeur de la clé primaire de l'objet en question est connue.

L'index utilisant le paramètre PROPERTY se construit d'après des colonnes (PK pour la clé primaire, Path pour le chemin d'accès, ainsi que la valeur du nœud) issues de l'index XML primaire, où PK correspond à la clé primaire de la table de base.

Par exemple, concernant le modèle de produit 19, la requête suivante extrait les valeurs des attributs ProductModelID et ProductModelName grâce à la méthode value(). Contrairement aux requêtes utilisant les index XML primaires ou tout autre index XML secondaire, l'index PROPERTY peut permettre une exécution plus rapide.

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS "PD")

SELECT CatalogDescription.value('(/PD:ProductDescription/@ProductModelID)[1]', 'int') as ModelID,
       CatalogDescription.value('(/PD:ProductDescription/@ProductModelName)[1]', 'varchar(30)') as ModelName        
FROM Production.ProductModel   
WHERE ProductModelID = 19

À part les différences décrites plus loin dans cette rubrique, la création d'un index XML portant sur une colonne de typexml est similaire à celle d'un index portant sur une colonne de type non xml. Les instructions DDL Transact-SQL suivantes permettent de créer et de gérer les index XML :