letture logiche vs. conteggio delle scansioni


8

Unisco una tabella piccola (1.000 righe) a una tabella grande (8 milioni di righe) in SQL Server 2008. Il join utilizza un indice di copertura non cluster sulla tabella grande e il join può produrre tre possibili piani di query. Sto cercando di capire quale piano è meglio, ma voglio anche generalizzare questa conoscenza, così la prossima volta posso sapere meglio quale euristica usare quando guardo le statistiche di I / O SQL.

Il piano n. 1 è un loop loop ed emette statistiche per la tabella di grandi dimensioni in questo modo:

Scan count 2582, logical reads 35686, physical reads 1041, read-ahead reads 23052

Il piano n. 2 è un join unione ed emette statistiche come questa:

Scan count 1, logical reads 59034, physical reads 49, read-ahead reads 59004

Il piano n. 3 è un hash join ed emette statistiche come questa:

Scan count 3, logical reads 59011, physical reads 5, read-ahead reads 59010

L'indice di copertura è ordinato per (ID, Date). La query restituisce dati per circa il 50% degli ID e, per ciascun ID, restituisce una parte contigua degli ultimi 3 mesi di dati, che di solito è circa 1/4 o le righe per ciascun ID. La query restituisce circa 1/8 delle righe totali nell'indice. In altre parole, la query è scarsa ma coerente.

La mia ipotesi è che il piano n. 1 sia terribile per questo carico di lavoro, perché spostare la testina del disco circa 2.500 volte (o anche 1.041 volte) è molto più costoso di una scansione sequenziale del disco. Suppongo anche che # 3 e # 2 abbiano modelli I / O simili, sequenziali (e quindi più efficienti).

Ma c'è un caso in cui il piano n. 1 è davvero il migliore, in cui "migliore" significa meno impatto sul sottosistema I / O e meno impatto su altre query in esecuzione contemporaneamente?

O dipende davvero da molte variabili come il tipo di sottosistema del disco che ho, la frammentazione dell'indice, ecc. Se "dipende" ci sono delle regole pratiche per affrontare il problema?


Le letture logiche sono dirette dal pool di buffer, le letture fisiche provengono dal disco, quindi sarebbe logico che tu voglia ridurre al minimo il numero di letture fisiche


Puoi pubblicare i tre piani di query come immagini?
usr

Risposte:


10

Ecco l'affare del killer: a gennaio costava $ 12k per acquistare 864 * GB * di RAM . Puoi ottenere un sacco di soldi per il buck semplicemente aumentando la RAM del tuo server fino al punto che non otterrai mai una lettura fisica (dopo il riscaldamento, ovviamente).

A parte questo, è davvero difficile dare un'opinione in bianco o nero su uno di quei punti dati che presenti. Il piano n. 1 aveva la maggior parte delle letture fisiche, ma sei sicuro che tutti i test siano stati eseguiti su cache riscaldata in modo simile? Potrebbe essere che il numero 1 abbia riscaldato la cache per il numero 2, qual è la tua metodologia di test per garantire che tutti i casi siano considerati su un piano di livello? Anche così, se sborsate $ 500 e raddoppiate la RAM, importerebbe di più? # 1 ha le letture meno logiche ...

Ma allora il numero 2 probabilmente trarrà beneficio da un DOP elevato (che una scansione può essere parallela). Il tempo dell'orologio a muro del 2 ° è migliore del 1 ° dopo aver aggiunto RAM sufficiente?

Quanti di questi piani corrono in parallelo? Ci sono decine di query che richiedono contemporaneamente una significativa concessione di memoria per l'hash n. 3 e quindi creando contesa per RESOURCE_SEMAPHORE? Il numero 2 sta facendo un ordinamento e richiede anche una concessione di memoria? # 1 funzionerà meglio poiché non richiede alcuna sovvenzione (almeno dalle informazioni pubblicate ...)?

È davvero relativo e la domanda che poni è più simile a trovare una soluzione per un complesso sistema di equazioni ... semplicemente potrebbe esserci più di una soluzione.

Una cosa è certa: le file da 8 M dovrebbero adattarsi alla RAM con molto spazio libero. Quelle letture fisiche chiedono alcuni banchi di memoria.


1

Per questa query apparentemente molto semplice, l'ottimizzatore produrrà costantemente il miglior piano in base al suo modello di costo. Il modello di costo è abbastanza preciso. Quindi la mia raccomandazione sarebbe di lasciare la scelta a SQL Server.

Seconda raccomandazione: misurare la durata della query per tutte e tre le varianti con una hot cache. Quindi decidere. (Non decidere in base a letture, scansioni e simili. Ciò che conta per te è la durata.)

In generale, per scegliere il miglior tipo di join (o indici) è necessario comprendere come funzionano gli algoritmi di join. Sono troppe informazioni per pubblicare qui.


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.