Condividi tramite


Indici XML secondari

Per migliorare le prestazioni di ricerca, è possibile creare indici XML secondari. A tale scopo, deve esistere innanzitutto un indice XML primario, prima di poterne creare di secondari. Tipi di indici secondari:

  • Indice XML secondario PATH

  • Indice XML secondario VALUE

  • Indice XML secondario PROPERTY

Di seguito sono riportate alcune linee guida per la creazione di uno o più indici di questo tipo:

  • Se nel carico di lavoro viene fatto un utilizzo significativo di espressioni di percorso sulle colonne XML, per migliorare le prestazioni di lavoro è possibile utilizzare l'indice XML secondario PATH. Il caso più comune è rappresentato dall'utilizzo del metodo exist() sulle colonne XML nella clausola WHERE di Transact-SQL.

  • Se il carico di lavoro recupera più valori da singole istanze XML utilizzando espressioni di percorso, può essere utile eseguire il clustering dei percorsi nell'ambito di ogni istanza XML nell'indice PROPERTY. Questa situazione si presenta in genere negli scenari che prevedono l'utilizzo di contenitori di proprietà, quando vengono recuperate le proprietà di un oggetto di cui è noto il valore della chiave primaria.

  • Se il carico di lavoro richiede l'esecuzione di query per il recupero di valori nelle istanze XML, senza conoscere i nomi degli elementi o attributi che contengono tali valori, sarà possibile creare l'indice VALUE. Questa situazione si verifica in genere nelle ricerche su assi discendenti, ad esempio //author[last-name="Howard"], in cui gli elementi <author> possono presentarsi a ogni livello della gerarchia. Si verifica inoltre nelle query che utilizzano caratteri jolly, ad esempio /book [@* = "novel"], in cui la query cerca elementi <book> contenenti un attributo con valore "novel".

Indice XML secondario PATH

Se in genere le query specificano espressioni di percorso nelle colonne di tipo xml, un indice secondario PATH potrebbe velocizzare la ricerca. Come precedentemente descritto in questo argomento, l'indice primario è utile nel caso di query che specificano il metodo exist() nella clausola WHERE. Se si aggiunge un indice secondario PATH, è possibile migliorare le prestazioni della ricerca in tali query.

Sebbene un indice XML primario consenta di evitare la suddivisione dei BLOB XML in fase di esecuzione, potrebbe non garantire prestazioni ottimali per le query basate su espressioni di percorso. Poiché in tutte le righe dell'indice XML primario corrispondenti a un BLOB XML viene eseguita la ricerca sequenziale di istanze XML di grandi dimensioni, tale ricerca potrebbe risultare lenta. In tal caso, l'utilizzo di un indice secondario basato sui valori di percorso e di nodo dell'indice primario può velocizzare in modo significativo la ricerca nell'indice. Nell'indice secondario PATH, i valori di percorso e di nodo sono colonne chiave che consentono ricerche di percorsi più efficienti. Query Optimizer può utilizzare l'indice PATH per espressioni analoghe alle seguenti:

  • /root/Location, in cui viene specificato solo un percorso

OR

  • /root/Location/@LocationID[.="10"], in cui vengono specificati sia il valore di percorso che il valore di nodo

Nella query seguente viene illustrato il caso in cui è utile l'indice PATH:

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

Nella query l'espressione di percorso /PD:ProductDescription/@ProductModelID e il valore "19" nel metodo exist() corrispondono ai campi chiave dell'indice PATH. In tal modo, è possibile eseguire una ricerca diretta nell'indice PATH e ottenere prestazioni di ricerca migliori rispetto a quelle della ricerca sequenziale di valori di percorso nell'indice primario.

Indice XML secondario VALUE

Se le query sono basate su valori, come ad esempio nel caso di /Root/ProductDescription/@*[. = "Mountain Bike"] o //ProductDescription[@Name = "Mountain Bike"], e il percorso specificato non è completo o include un carattere jolly, è possibile velocizzare la ricerca compilando un indice XML secondario basato sui valori di nodo dell'indice XML primario.

Le colonne chiave dell'indice VALUE sono il valore di nodo e il percorso dell'indice XML primario. Se il carico di lavoro implica l'esecuzione di query per valori da istanze XML senza conoscere i nomi di elemento o di attributo che contengono tali valori, un indice VALUE può risultare utile. Ad esempio, un indice VALUE risulta vantaggioso per l'espressione seguente:

  • //author[LastName="someName"], in cui si conosce il valore dell'elemento <LastName> ma l'elemento padre <author> può ricorrere in qualsiasi posizione.

  • /book[@* = "someValue"], in cui la query esegue la ricerca dell'elemento <book> che include attributi con il valore "someValue".

La query seguente restituisce BusinessEntityID dalla tabella Person. La clausola WHERE specifica un filtro che esegue la ricerca di valori nella colonna di tipo AdditionalContactInfoxml. Gli ID delle entità commerciali vengono restituiti solo se il BLOB XML con le informazioni contatto aggiuntive corrispondenti include un numero di telefono specifico. Poiché l'elemento <telephoneNumber> può ricorrere in qualsiasi posizione all'interno dell'istanza XML, l'espressione di percorso specifica l'asse descendent-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 BusinessEntityID 
FROM   Person.Person
WHERE  AdditionalContactInfo.exist('//ACT:telephoneNumber/ACT:number[.="111-111-1111"]') = 1

In tal caso, si conosce il valore di ricerca per <number>, ma tale valore può ricorrere in qualsiasi posizione all'interno dell'istanza XML come elemento figlio dell'elemento <telephoneNumber>. Per questo tipo di query può risultare utile eseguire una ricerca nell'indice basata su un valore specifico.

Indice secondario PROPERTY

Per le query che recuperano uno o più valori da singole istanze XML può essere utile un indice PROPERTY. Questa situazione si verifica quando si recuperano proprietà dell'oggetto tramite il metodo value() del tipo xml e quando si conosce il valore della chiave primaria dell'oggetto.

L'indice PROPERTY viene compilato in base alle colonne PK e Path e al valore di nodo dell'indice XML primario, in cui PK è la chiave primaria della tabella di base.

Ad esempio, per il modello di prodotto 19, la query seguente recupera i valori degli attributi ProductModelID e ProductModelName tramite il metodo value(). Anziché utilizzare l'indice XML primario o gli altri indici XML secondari, l'indice PROPERTY consente di velocizzare l'esecuzione.

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

Ad eccezione delle differenze descritte più avanti in questo argomento, la creazione di un indice XML in una colonna di tipoxml è simile alla creazione di un indice in una colonna di tipo non xml. Per la creazione e la gestione di indici XML, è possibile utilizzare le istruzioni DDL Transact-SQL seguenti: