È male avere uno spazio indice più grande dello spazio dati?


22

Spesso ho bisogno di eseguire query su tabelle di grandi dimensioni che non hanno l'indice giusto. Quindi chiedo al DBA di creare tale indice. La prima cosa che fa è guardare le statistiche della tabella e vedere la dimensione dello spazio dell'indice.

Spesso mi diceva di trovare una soluzione alternativa perché "l'indice è già più grande della tabella". Sente che l'indice deve essere più piccolo dei dati, perché mi ha detto "hai mai visto l'indice in un libro? È molto più piccolo del libro stesso, ed è così che dovrebbe essere un indice di tabella".

Non credo che la sua filosofia sia corretta, ma non posso sfidarlo perché è un DBA principale e sono uno sviluppatore. Sento che se una query necessita di un indice, l'indice dovrebbe essere appena creato, invece di trovare "soluzioni alternative" che rendono SP illeggibili e non mantenibili.

Sto selezionando solo le colonne richieste. Il problema è che sto filtrando per data, quindi il motore eseguirà necessariamente una scansione della tabella per abbinare le colonne. La query viene eseguita una volta al giorno, di notte, per raccogliere statistiche, ma sono necessari 15 minuti per l'esecuzione (abbiamo un'altra regola rigida e veloce: nessuna procedura dovrebbe richiedere più di 3 minuti).

Il DBA mi ha mostrato le statistiche dell'indice. C'erano circa 10 indici su quella tabella, di cui solo 6 erano usati (le statistiche mostravano zero hit a 4 di essi). Questo è un grande sistema con oltre 20 sviluppatori partecipanti. Gli indici sono stati creati per qualsiasi motivo e probabilmente non vengono più utilizzati.

Siamo tenuti a supportare SQL Server 2008, poiché è quello su cui vengono eseguiti i DB di test. Ma i clienti sono tutti sul 2014 e 2016.

Risposte:


34

Pensa al design dell'indice come a un interruttore scorrevole. Puoi spostare questa manopola dell'interruttore a triangolo rosso ovunque lungo la linea che desideri:

Decisioni di progettazione dell'indice

Di solito non lo misuro in termini di dimensioni - di solito ci penso in termini di quantità di indice, ma anche le dimensioni andrebbero bene.

Sembra che il tuo DBA pensi che l'interruttore sia troppo lontano a destra - che hai aggiunto troppi indici e che le eliminazioni / gli aggiornamenti / gli inserti si stanno comportando troppo lentamente.

Invece di discutere su dove si trova l'interruttore, prova a chiedergli quali sono i problemi di prestazioni dovuti all'alto numero di indici. Forse i tuoi utenti si lamentano della velocità di eliminazione / aggiornamento / inserimento, o sta vedendo attese di blocco o sta facendo fatica a eseguire il backup del database a causa delle sue dimensioni.

Il mio punto di partenza è di solito 5 e 5: circa 5 indici per tabella, con circa 5 o meno campi per indice. Non c'è nulla di magico in quel numero - deriva solo dal fatto che ho 5 dita per mano, quindi è facile alzare le mani e spiegare la regola.

Potrebbe essere necessario avere molti indici MENO di 5 quando il carico di lavoro è fortemente distorto verso le operazioni di eliminazione / aggiornamento / inserimento e non si dispone di una potenza hardware sufficiente per tenere il passo.

Potresti essere in grado di avere molti PIÙ indici quando il tuo carico di lavoro è per lo più di sola lettura o quando investi pesantemente in hardware (come cache l'intero database in memoria e sotto tutto lo storage a stato solido).


4

Anche il desiderio di avere più di "The Ozar 5" su una tabella probabilmente indica che sul tavolo ci sono molti tipi diversi di query pesanti.

Il che probabilmente indica che potresti beneficiare di un indice columnstore cluster o non cluster sulla tabella.

Invece di avere l'indice ottimale per ciascuno dei N percorsi di accesso diversi, un archivio colonne ti offre una scansione superveloce e la possibilità di saltare colonne e segmenti di riga non necessari. Quindi puoi avere un piccolo numero di indici BTree per transazioni super-critiche e tornare al columnstore per tutto il resto.

Gli indici Columnstore sono progettati per funzionare con carichi di lavoro pesanti OLTP con SQL Server 2016+. Consulta la documentazione per Analisi operative in tempo reale .


3

Mi piace la risposta di Brents e l'ho votata. Vorrei aggiungere un'altra prospettiva però. Ho lavorato come utente, sviluppatore e DBA e ritengo che le opinioni non siano pertinenti. Credo che spetti all'utente (o allo stakeholder) decidere come si comporta una query e quanto tempo ci vuole per ottenere risultati. Spetta quindi allo sviluppatore e al DBA lavorare insieme per realizzarlo.

Se la posizione DBA nella tua azienda è "responsabile" di questo argomento, possono analizzare la tua query e formulare suggerimenti su una migliore progettazione della query oppure rispondere per le prestazioni.

Se la query e / o la struttura dei dati non possono essere modificate per raggiungere l'obiettivo, penso che si riducano a tre scelte.

  1. Recupero lento dei dati
  2. Aggiornamento lento dei dati
  3. Altre risorse hardware $$$$

Naturalmente ogni situazione ha molte variabili che dipendono da molteplici fattori aziendali e tecnologici, ma credo che le tre opzioni si applichino alla maggior parte, se non a tutti i casi.


0

Sembra troppo severo per vietare gli indici> tabella. Se il tuo tavolo cambia raramente (o cambia di notte quando non c'è molta concorrenza per le risorse) e viene interrogato molto in molti modi diversi, molti grandi indici possono essere giustificati. I DBA dovrebbero anche fare attenzione a non infilare il naso dove non appartiene. Se dà a te / al tuo sistema un limite di gigabyte, non dovrebbe preoccuparsi troppo di come viene utilizzato quello spazio. Se è oberato di lavoro, questo potrebbe essere il motivo.

Tuttavia ci sono molte cose da considerare:

  • Molti indici rendono gli inserimenti / aggiornamenti / eliminazioni più lenti. Quindi, se la tua tabella cambia molto, fai attenzione a non farne troppe.
  • Anche lo spazio può essere un problema. Non solo perché i gigabyte costano denaro (non molto al giorno d'oggi), ma anche il tempo trascorso dal momento che il backup sarà più lento (a seconda di come viene eseguito il backup).
  • I database più gravi possono essere monitorati per trovare indici usati raramente o mai. Valuta di lasciarne alcuni.
  • A volte pensi di aver bisogno di un indice, ma quando esamini più da vicino la tua query può essere sintonizzata e riscritta in modo diverso con lo stesso risultato e senza la necessità dell'indice. Usa il piano esplicativo per vedere se l'indice viene utilizzato o meno.
  • A volte le ultime colonne possono essere eliminate da un indice multi-colonna senza un notevole calo delle prestazioni. E a volte questo può persino rendere le query più veloci perché lo spazio di archiviazione dell'indice è più piccolo e una parte maggiore dell'indice verrà mantenuta / memorizzata nella memoria in qualsiasi momento.
  • Gli indici basati su funzioni possono sostituire quelli normali per risparmiare più spazio. Esempio: anziché eseguire una query per il cognome completo, eseguire una query anche per le prime due lettere ( where substr(surname, 1, 2) = substr(<userinput>, 1, 2) and surname=<userinput>) e create index i on customers(substr(surname,1,2)). Questo potrebbe essere abbastanza veloce e il tuo indice sarà più piccolo.
  • I database supportano diversi tipi di indici. Alcuni tipi utilizzano meno spazio di altri. Forse alcuni dei tuoi indici possono essere convertiti in un tipo che richiede meno spazio? Assicurati di capire prima i diversi tipi di indice e per quali situazioni sono buoni e cattivi.
  • Se un processo batch non frequente è l'unica cosa che necessita di un indice specifico, prendere in considerazione la creazione di tale indice solo per quel processo batch e rilasciarlo in seguito.
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.