Differenze di righe stimate rispetto a quelle effettive (effettive molto inferiori alle stime) - ordinamento


8

Sto eseguendo una query che sta elaborando alcuni nodi da un documento XML. Il mio costo di sottostruttura stimato è in milioni e sembra che tutto provenga da un'operazione di ordinamento che il server sql sta eseguendo su alcuni dati che estraggo dalle colonne XML tramite XPath. L'operazione di ordinamento ha un numero stimato di righe pari a circa 19 milioni, mentre il conteggio delle righe effettive è di circa 800. La query stessa funziona abbastanza bene (1 - 2 secondi), ma la discrepanza mi fa riflettere sulle prestazioni della query e perché questo la differenza è così grande?


2
Ciò è probabilmente dovuto a statistiche obsolete, ma è davvero impossibile dirlo senza ulteriori informazioni (tra cui la struttura / indici della tabella, la query e un piano di esecuzione effettivo - non stimato).
Aaron Bertrand

1
In base alla mia esperienza, i piani di query che prevedono la distruzione di XML hanno sempre stime di costo notevolmente gonfiate. Ad esempio, al punto che se la query funziona bene in termini di tempo di esecuzione, ignoro semplicemente i numeri della stima dei costi. Non ho idea del perché lo faccia, ma potrebbe avere qualcosa a che fare con il non sapere quanto XML verrà utilizzato come input. Se il tuo obiettivo è migliorare le prestazioni della query, tuttavia, un modo che ho scoperto è utilizzare raccolte di schemi XML, come ho scritto qui sul blog .
Jon Seigel,

Risposte:


9

Non ci sono statistiche generate su colonne XML. Le stime sono indovinate in base alle espressioni utilizzate durante l'interrogazione dell'XML.

Utilizzando questa tabella:

create table T(XMLCol xml not null)
insert into T values('<root><item value = "1" /></root>')

E questa query XML piuttosto semplice:

select X.N.value('@value', 'int')
from T
  cross apply T.XMLCol.nodes('root/item') as X(N)

Ti verrà restituita una riga ma le righe stimate restituite sono 200. Saranno 200 indipendentemente da quale XML o quanto XML inserirai nella colonna XML per quella riga.

Questo è il piano di query con il conteggio delle righe stimato visualizzato.

inserisci qui la descrizione dell'immagine

Un modo per migliorare, o almeno modificare, le stime è fornire all'ottimizzatore di query ulteriori informazioni sull'XML. In questo caso, poiché so che rootè davvero un nodo radice nell'XML, posso riscrivere la query in questo modo.

select X2.N.value('@value', 'int')
from T
  cross apply T.XMLCol.nodes('root[1]') as X1(N)
  cross apply X1.N.nodes('item') X2(N)

Questo mi darà una stima di 5 righe restituite.

inserisci qui la descrizione dell'immagine

La riscrittura della query probabilmente non accelererà la distruzione dell'XML ma se le stime sono migliori, è probabile che Query Optimizer possa prendere decisioni più intelligenti per il resto della query.

Non ho trovato alcuna documentazione su quali siano le regole per le stime diverse da una presentazione di Michael Rys in cui dice:

La stima della cardinalità di base è sempre di 10'000 righe!
Alcune regolazioni basate su filtri del percorso spinto

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.