Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Perché questa è una scansione dell'indice e non una ricerca dell'indice?

Utilizza una scansione dell'indice principalmente perché utilizza anche un join unione. L'operatore Merge Join richiede due flussi di input che sono entrambi ordinati in un ordine compatibile con le condizioni di join.

E sta usando l'operatore Merge Join per realizzare il tuo INNER JOIN perché crede che sarà più veloce del più tipico operatore Nested Loop Join. Ed è probabilmente giusto (di solito lo è), utilizzando i due indici che ha scelto, ha flussi di input che sono entrambi preordinati in base alla condizione di join (LocationID). Quando i flussi di input sono preordinati in questo modo, i Merge Join sono quasi sempre più veloci degli altri due (Loop e Hash Join).

Lo svantaggio è quello che hai notato:sembra scansionare l'intero indice, quindi come può essere più veloce se sta leggendo così tanti record che potrebbero non essere mai utilizzati? La risposta è che le scansioni (a causa della loro natura sequenziale) possono leggere da 10 a 100 volte il numero di record al secondo che cerca.

Now Seek di solito vincono perché sono selettivi:ottengono solo le righe che chiedi, mentre le scansioni non sono selettive:devono restituire ogni riga nell'intervallo. Ma poiché le scansioni hanno un molto velocità di lettura più elevata, possono spesso battere le ricerche fintanto che il rapporto tra le righe scartate e le righe corrispondenti è inferiore rispetto al rapporto di Scansione righe/sec VS. Cerca righe/sec.

Domande?

OK, mi è stato chiesto di spiegare meglio l'ultima frase:

Una "riga scartata" è quella che legge la scansione (perché deve leggere tutto nell'indice), ma che verrà rifiutata dall'operatore Merge Join, perché non ha una corrispondenza sull'altro lato, probabilmente perché il La condizione della clausola WHERE l'ha già esclusa.

"Righe corrispondenti" sono quelle che ha letto che sono effettivamente abbinate a qualcosa nel Merge Join. Queste sono le stesse righe che sarebbero state lette da una ricerca se la scansione fosse stata sostituita da una ricerca.

Puoi capire cosa ci sono guardando le statistiche nel Query Plan. Vedi quell'enorme freccia grossa a sinistra della scansione dell'indice? Ciò rappresenta quante righe l'ottimizzatore pensa di leggere con la scansione. La casella delle statistiche della scansione dell'indice che hai pubblicato mostra che le righe effettive restituite sono circa 5,4 milioni (5.394.402). Questo è uguale a:

TotalScanRows = (MatchingRows + DiscardedRows)

(Ai miei termini, comunque). Per ottenere le righe corrispondenti, guarda le "righe effettive" riportate dall'operatore Merge Join (potresti dover togliere la TOP 100 per ottenere questo in modo accurato). Una volta che lo sai, puoi ottenere le righe Scartate da:

DiscardedRows = (TotalScanRows - MatchingRows)

E ora puoi calcolare il rapporto.