Domanda

Un collega mi ha chiesto di esaminare l'indicizzazione su alcune tabelle perché la sua query era in esecuzione da molto tempo. Più di un'ora.

select count(1)
from databaseA.dbo.table1
inner join databaseA.dbo.table2 on (table1.key = table2.key)
inner join databaseB.dbo.table3 on (table1.key = table3.key)

Nota i diversi database. Questo è stato eseguito da DatabaseB

Le tabelle 1 e 2 erano lunghe oltre 2 milioni di record. Table3 aveva una dozzina di record circa.

Ho esaminato il piano di query e l'ottimizzatore ha deciso di eseguire ricerche nell'indice a ciclo nidificato nelle tabelle 1 e 2 con Table3 come tabella guida!

La mia prima ipotesi era che le statistiche fossero gravemente incasinate su Tables1 & amp; 2 ma prima di aggiornare le statistiche ho provato ad aggiungere un suggerimento di join in tal modo:

select count(1)
from databaseA.dbo.table1
inner HASH join databaseA.dbo.table2 on (table1.key = table2.key)
inner join databaseB.dbo.table3 on (table1.key = table3.key)

Risultati restituiti in 15 secondi.

Dato che avevo poco tempo, gli ho passato i risultati ma sono preoccupato che ciò possa causare problemi lungo la strada.

Devo rivisitare il problema delle statistiche e risolvere il problema in quel modo? Il piano di query errato potrebbe derivare dall'unione proveniente da un database separato?

Qualcuno può offrirmi alcune idee in base alla tua esperienza?

È stato utile?

Soluzione

Vorrei prima sospettare le statistiche.

Come sicuramente sapete, i suggerimenti di Join dovrebbero essere evitati nel 99% dei casi e usati solo quando si ha la prova che sono assolutamente necessari.

Altri suggerimenti

Controlla prima le statistiche e l'indicizzazione sulla tabella. I suggerimenti sull'indice possono causare problemi. Se i dati nelle tabelle cambiano, l'ottimizzatore non sarà in grado di scegliere un piano più efficace poiché lo hai costretto a utilizzare sempre un hash.

Un loop nidificato non sarebbe il più appropriato? Prendi i 12 record dalla tabella 3, abbina i 12 record nella tabella 1, abbina i 12 record nella tabella 2.

Altrimenti, anche il tuo hash join importerebbe anche l'ordinamento, il che significa che avresti hash 1 milione di record dalla Tabella 1 e dalla Tabella 2, quindi aderisci ai 12 record nella Tabella 3.

Esaminerei le statistiche per entrambi i piani e sospetto che il loop join sia effettivamente più efficiente, ma è stato bloccato o il tuo hash join stava sfruttando i dati memorizzati nella cache.

Ma - sì - in generale, i suggerimenti sui join sono l'ultima risorsa.

Una query a esecuzione lenta che coinvolge server collegati potrebbe avere a che fare con le regole di confronto. Vedi qui per alcuni retroscena: http://blogs.msdn.com/psssql/archive/2008/02/14/how-it-works-linked-servers-and-collation-compatibility.aspx Il suggerimento di hash join forza l'ordinamento, quindi questo spiega il miglioramento delle prestazioni.

Ecco come impostare le opzioni:

EXEC master.dbo.sp_serveroption 
    @server=N'databaseA', 
    @optname=N'collation compatible', 
    @optvalue=N'true'

EXEC master.dbo.sp_serveroption 
    @server=N'databaseA', 
    @optname=N'use remote collation', 
    @optvalue=N'false'

-Edoode

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top