"Avvertenze: operazione causata I / O residuo" rispetto a ricerche chiave


9

Ho visto questo avviso nei piani di esecuzione di SQL Server 2017:

Avvertenze: l'operazione ha causato IO residuo [sic]. Il numero effettivo di righe lette era (3.321.318), ma il numero di righe restituite era 40.

Ecco uno snippet di SQLSentry PlanExplorer:

Inserisci qui la descrizione dell'immagine

Per migliorare il codice, ho aggiunto un indice non cluster, in modo che SQL Server possa accedere alle righe pertinenti. Funziona bene, ma normalmente ci sarebbero troppe (grandi) colonne da includere nell'indice. Sembra così:

Inserisci qui la descrizione dell'immagine

Se aggiungo solo l'indice, senza includere le colonne, è simile al seguente, se forzo l'uso dell'indice:

Inserisci qui la descrizione dell'immagine

Ovviamente, SQL Server ritiene che la ricerca delle chiavi sia molto più costosa dell'I / O residuo. Ho una configurazione di test senza molti dati di test (ancora), ma quando il codice entra in produzione, deve funzionare con molti più dati, quindi sono abbastanza sicuro che sia necessaria una sorta di indice non cluster.

Le ricerche chiave sono davvero così costose , quando si esegue su SSD, che devo creare indici full-fat (con molte colonne include)?


Piano di esecuzione: https://www.brentozar.com/pastetheplan/?id=SJtiRte2X Fa parte di una lunga procedura memorizzata. Cercare IX_BatchNo_DeviceNo_CreatedUTC.


Domanda per te: in base al tuo ultimo paragrafo, perché il costo di una ricerca dovrebbe essere inferiore in base all'hardware? (Presumibilmente lo stesso hardware su cui verrà eseguito l'indice non cluster) Non sono chiaro su questo.
George.Palacios,

4
Si stima che sia il 76,9% del costo di quel piano . Ciò non significa che sia costoso. Guarda il costo di I / O di 0,06 rispetto al tuo piano originale con un costo di I / O superiore a 10. Penso che starai meglio, ma dovresti testare con piani effettivi rispetto a dati sufficienti che simulano davvero come sarà la produzione ( e se la query viene eseguita abbastanza a lungo da cui raccogliamo i dati sys.dm_exec_query_profiles, li rimborseremo dai costi effettivi rispetto alla stima). Smetti di usare il costo stimato% come un indicatore assoluto del costo: è relativo e spesso è fuori a pranzo.
Aaron Bertrand

@AaronBertrand; il costo stimato delle ricerche chiave è 31,0. Mi stai dicendo che SQL Server non conosce il costo dell'IO residuo?
Henrik Staun Poulsen,

Dove vedi 31.0? E intendi il 31,0 o il 31,0%?
Aaron Bertrand

1
No, sto dicendo che i costi che vedi sono costi stimati e, come spiega Paul sotto, non riflettono necessariamente le prestazioni di runtime.
Aaron Bertrand

Risposte:


16

Il modello di costo utilizzato dall'ottimizzatore è esattamente questo: un modello . Produce generalmente buoni risultati su una vasta gamma di carichi di lavoro, su una vasta gamma di progetti di database, su una vasta gamma di hardware.

Generalmente non si deve presumere che le singole stime dei costi siano fortemente correlate alle prestazioni di runtime su una particolare configurazione hardware. Il punto di determinazione dei costi è consentire all'ottimizzatore di effettuare una scelta consapevole tra le alternative fisiche candidate per la stessa operazione logica.

Quando si entra davvero nei dettagli, un esperto database esperto (con il tempo libero di mettere a punto una query importante) può spesso fare di meglio. In tal senso, puoi considerare la selezione del piano dell'ottimizzatore come un buon punto di partenza. Nella maggior parte dei casi, quel punto di partenza sarà anche il punto finale, poiché la soluzione trovata è abbastanza buona .

Nella mia esperienza (e opinione) l'ottimizzatore di query di SQL Server costa ricerche più elevate di quanto preferirei. Questo è in gran parte una sbronza dai tempi in cui l'I / O fisico casuale era molto più costoso rispetto all'accesso sequenziale di quanto spesso accade oggi.

Tuttavia, le ricerche possono essere costose anche su SSD o alla fine anche quando si leggono esclusivamente dalla memoria. Attraversare le strutture b-tree non è gratuito. Ovviamente il costo aumenta man mano che ne fai di più.

Le colonne incluse sono ottime per i carichi di lavoro OLTP a lettura pesante, in cui il compromesso tra l'utilizzo dello spazio dell'indice e il costo dell'aggiornamento rispetto alle prestazioni di lettura del runtime ha senso. C'è anche un compromesso da considerare riguardo alla stabilità del piano . Un indice a copertura totale evita la questione di quando esattamente il modello di costo dell'ottimizzatore potrebbe passare da un'alternativa all'altra.

Solo tu puoi decidere se valgono i compromessi nel tuo caso. Testare entrambe le alternative su un campione di dati rappresentativo ed effettuare una scelta informata.

In un commento a una domanda hai aggiunto:

Mi stai dicendo che SQL Server non conosce il costo dell'IO residuo?

No, l'ottimizzatore considera il costo dell'I / O residuo. In effetti, per quanto riguarda l'ottimizzatore, i predicati non SARGable sono valutati in un filtro separato. Questo filtro viene inserito nella ricerca o nella scansione come residuo durante le riscritture post-ottimizzazione .


Grazie mille per la tua risposta. Proverò a seguire i tuoi consigli sui dati di test, in modo da poter capire quale indice ho davvero bisogno. È bene sapere che pensi che le ricerche dovrebbero costare meno sugli SSD. Fa ben sperare per vNext.
Henrik Staun Poulsen,
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.