Quando è meglio creare STATISTICHE anziché creare un indice?


38

Ho trovato molte informazioni su cosa STATISTICS sono: come vengono gestite, come possono essere create manualmente o automaticamente da query o indici e così via. Ma non sono stato in grado di trovare alcuna guida o informazione sulle "migliori pratiche" in merito a quandoper crearli: quali situazioni beneficiano maggiormente di un oggetto STATISTICA creato manualmente che di un indice. Ho visto statistiche filtrate create manualmente che aiutano le query su tabelle partizionate (perché le statistiche create per gli indici coprono l'intera tabella e non sono per partizione - brillante!), Ma sicuramente ci devono essere altri scenari che trarrebbero beneficio da un oggetto statistico mentre non necessita del dettaglio di un indice, né vale la pena sostenere il mantenimento dell'indice o aumentare le possibilità di blocco / dead-lock.

@JonathanFite, in un commento, ha menzionato una distinzione tra indici e statistiche:

Gli indici aiuteranno SQL a trovare i dati più velocemente creando ricerche ordinate in modo diverso rispetto alla tabella stessa. Le statistiche aiutano SQL a determinare quanta memoria / sforzo sarà necessario per soddisfare la query.

Questa è un'ottima informazione, soprattutto perché mi aiuta a chiarire la mia domanda:

Come funziona sapendo questo (o qualsiasi altra informazione tecnica sulla quale s e come s relativi ai comportamenti e la natura di STATISTICS) aiutare a determinare se scegliere CREATE STATISTICSsopra CREATE INDEX, soprattutto quando si crea un indice creerà il relativo STATISTICSoggetto? Quale scenario sarebbe meglio se si avessero solo le informazioni STATISTICHE e non si avesse l'Indice?

Sarebbe utile, se possibile, il super-duper avere un esempio funzionante di uno scenario in cui l' STATISTICSoggetto si adatta meglio di un INDEX.


Dato che io sono uno studente / pensatore visivo, ho pensato che potrebbe aiutare a vedere le differenze tra STATISTICSe INDEXES, fianco a fianco, come un possibile mezzo per aiutare a determinare se STATISTICSsono la scelta migliore.

Thingy           PROs                             CONs
-------          ----------                       -------------------
INDEX            * Can help sorts.                * Takes up space.
                 * Contains data (can             * Needs to be maintained (extra I/O).
                   "cover" a query).              * More chances for blocking / dead-locks.

STATISTICS       * Takes up very little space.    * Cannot help sorts.
                 * Lighter maintenance / won't    * Cannot "cover" queries.
                   slow down DML operations.
                 * Does not increase chances
                   of blocking / dead-locks.

Di seguito sono riportate alcune risorse che ho trovato durante la ricerca di questo, uno che pone anche la stessa domanda, ma non ha ricevuto risposta:

SQL Server Index vs Statistic

Domande sulle statistiche di SQL Server che eravamo troppo timidi da porre

Statistiche. Sono possibili istogrammi a più colonne?

** Per essere chiari, non ho una risposta per questo e in realtà sto cercando di ricevere feedback da alcune persone speriamo di fornire quelle che sembrano essere stranamente informazioni mancanti qui nell'interwebs.


1
Gli indici aiuteranno SQL a trovare i dati più velocemente creando ricerche ordinate in modo diverso rispetto alla tabella stessa. Le statistiche aiutano SQL a determinare quanta memoria / sforzo sarà necessario per soddisfare la query.
Jonathan Fite,

@JonathanFite Grazie per quel commento. L'ho incorporato nella mia domanda :).
Solomon Rutzky,

Seguendo il commento di @ JonathanFite sembrerebbe che le statistiche siano le migliori per aumentare le prestazioni su sistemi / tabelle / schemi di query ad hoc, mentre gli indici sono migliori per schemi di query prevedibili. Intendo questo più come una domanda che come un'affermazione.
Dave,

Risposte:


19

La tua domanda ruota attorno - Quando è una buona cosa creare statistiche e creare indici (che creano statistiche).

Dalle mie note interne al server sql (classe SQLSkills - IE1 e IE2) e dal libro interno su SQL Server , di seguito è una mia comprensione limitata :

Le statistiche di SQL Server non sono altro che oggetti di sistema che contengono informazioni vitali sui valori della chiave di indice e sui valori di colonna regolari.

SQL Server utilizza un modello basato sui costi per scegliere un piano di esecuzione "abbastanza buono" il più rapidamente possibile. La stima della cardanilità (stima del numero di righe da elaborare su ogni fase dell'esecuzione della query) è il fattore più importante nell'ottimizzazione della query che a sua volta influenza la strategia di join, il requisito di concessione di memoria, la selezione del thread di lavoro e la scelta degli indici durante l'accesso ai dati .

SQL Server non utilizzerà indici non cluster quando stima che un numero elevato. delle operazioni di loopup KEY o RID saranno necessarie, quindi mantiene statistiche sugli indici (e sulle colonne) che aiuteranno in tali stime.

Ci sono 2 cose importanti sulle statistiche:

  1. L'istogramma memorizza SOLO le informazioni sulla distribuzione dei dati per la colonna delle statistiche (indice) più a sinistra. Memorizza inoltre informazioni sulla densità multi colonna dei valori chiave. Quindi, in sostanza, l'istogramma memorizza la distribuzione dei dati solo per la colonna delle statistiche più a sinistra.

  2. SQL Server manterrà al massimo 200 passaggi nell'istogramma indipendentemente dalle dimensioni della tabella. Gli intervalli coperti da ciascun passaggio dell'istogramma aumentano con l'aumentare della tabella, il che porta a statistiche "meno accurate" per le tabelle di grandi dimensioni.

    Ricorda che la selettività dell'indice è una metrica inversamente proporzionale alla densità, ovvero più valori univoci hanno una colonna, maggiore è la sua selettività.

Quando query particolari non vengono eseguite molto spesso, è possibile selezionare di creare statistiche a livello di colonna anziché un indice. Le statistiche a livello di colonna aiutano lo Strumento per ottimizzare le query a trovare piani di esecuzione migliori, anche se tali piani di esecuzione non sono ottimali a causa delle scansioni dell'indice coinvolte. Allo stesso tempo, le statistiche non aggiungono un sovraccarico durante le operazioni di modifica dei dati e aiutano a evitare la manutenzione dell'indice. Questo approccio funziona solo per le query eseguite raramente.

Fare riferimento :

Nota: qualcuno come Paul White o Aaron Bertrand può intervenire per fornire più colore alla tua buona domanda .


"SQL Server non utilizzerà indici non cluster quando stima che sarà richiesto un numero elevato di operazioni di loopup KEY o RID" Quindi, il QO può utilizzare l'oggetto stats in base a un indice indipendentemente dall'indice? Significato, se l'indice non è ottimale, ma la colonna principale è nella query, le statistiche sono comunque rilevanti. Quindi sarebbero stati usati? O queste informazioni implicano che potrebbero esserci casi in cui un indice non verrebbe probabilmente usato, ma poiché le statistiche hanno ancora valore, quindi nessun vero motivo per creare l'indice, basta fare le statistiche?
Solomon Rutzky,

8

Direi che hai bisogno di un indice quando devi essere in grado di limitare la quantità di dati / ottenere rapidamente i dati corretti in base ai campi.

Sono necessarie statistiche quando è necessario l'ottimizzatore per comprendere la natura dei dati per essere in grado di eseguire le operazioni nel miglior modo possibile.

Ciò che ho capito, le statistiche filtrate aiutano quando si hanno inclinazioni nei dati che incidono pesantemente sul piano, ad esempio nello stack overflow pochi utenti hanno un numero enorme di post, quindi l'utilizzo di soli post medi per utente non è davvero la migliore stima. Quindi potresti creare una statistica filtrata su userId in base al nome utente e quindi SQL Server dovrebbe sapere che quando questo nome utente è nella query, questo è l'ID utente che otterrà e dovrebbe essere in grado di capire che il il campo indicizzato nella tabella dei post avrà un'enorme quantità di righe con quell'id perché esiste un istogramma. Con le medie, non è possibile farlo.


1
Ciao e grazie per aver risposto. Quindi, quando avrei bisogno / desidererei che l'ottimizzatore comprendesse meglio la natura dei dati, senza tuttavia limitare i dati o volerli raggiungere più velocemente, o averne bisogno per "coprire" la query? Lo stesso per il tuo esempio di indice filtrato. Capisco quello che stai dicendo in termini di distacco dei casi limite dalle medie, ma perché le statistiche filtrate dovrebbero essere migliori di un indice filtrato sugli stessi campi? Questa è la distinzione che sto cercando di ottenere.
Solomon Rutzky,

Come nell'esempio, non è possibile creare un indice filtrato sul nome utente nella tabella dei post perché non esiste lì. È possibile crearlo in base all'ID utente, ma non è nella clausola where.
James Z,

Ma non UserIDsarebbe nella condizione JOIN, anche se non nella WHERE? E non sarebbe abbastanza buono per raccogliere un indice filtrato?
Solomon Rutzky,

@srutzky Forse più probabilmente nelle versioni più attuali, ma in generale non mi affiderei a questo ... nella maggior parte dei casi, i predicati devono corrispondere esattamente. Dimentico se hanno risolto questo problema, ma a un certo punto un indice filtrato WHERE BitColumn = 0non sarebbe stato selezionato per una semplice query WHERE BitColumn <> 1. (E per essere chiari, la colonna di bit non era nulla.) Penso che ci fossero casi simili come IntColumn > 10non corrispondenti IntColumn >= 11.
Aaron Bertrand

Gli indici filtrati non possono essere utilizzati se esiste la possibilità che la prossima volta che qualcuno usi i piani l'indice filtrato non sia più adatto. Non riesco a pensare a nessun join che potrebbe utilizzare un indice filtrato. Anche le variabili non possono essere utilizzate perché la prossima volta il valore potrebbe essere qualcosa di non adatto.
James Z,

4

Dal 70-461 Libro di formazione di Itzik Ben-Gan

Ci sono solo alcuni possibili motivi per creare manualmente le statistiche. Un esempio è quando un predicato di query contiene più colonne con relazioni tra colonne; le statistiche su più colonne possono aiutare a migliorare il piano di query. Le statistiche su più colonne contengono densità di colonne che non sono disponibili nelle statistiche a colonna singola. Tuttavia, se le colonne sono già nello stesso indice, l'oggetto statistico a più colonne esiste già, quindi non è necessario crearne uno manualmente.


Grazie per aver pubblicato questo Questo risponde a una parte della mia domanda, ma lascia comunque aperta la domanda di: se ho bisogno delle statistiche multi-colonna, perché dovrei creare solo STATISTICHE invece dell'Indice, che includerebbe STATISTICHE più informazioni aggiuntive che potrebbero aiutare ulteriormente la query ( ies)?
Solomon Rutzky,

1
Penso che la spiegazione di Kin spiegherebbe ulteriormente cosa stai cercando. Forse un heap che viene frequentemente inserito, ma raramente interrogato?
Kentaro,
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.