Effetto di un indice sulle istruzioni di aggiornamento in cui la colonna di aggiornamento non si trova in un indice


16

Ho sempre visto la gente dice che gli indici rallentano update, deletee insert. Questo è usato come un'istruzione coperta, come se fosse un assoluto.

Mentre ottimizzo il mio database per migliorare le prestazioni, continuo a imbattermi in questa situazione che sembra contraddire logicamente quella regola per me, e da nessuna parte posso trovare qualcuno che dica o spieghi in altro modo.

In SQL Server, e credo / presumo che la maggior parte degli altri DBMS, gli indici vengano creati in base a colonne specifiche specificate. Inserimenti ed eliminazioni influenzeranno sempre un'intera riga, quindi non è possibile che non influenzino l'indice, ma gli aggiornamenti sembrano un po 'più unici, possono influenzare in modo specifico solo determinate colonne.

Se ho colonne che non sono incluse in nessun indice e le aggiorno, sono rallentate solo perché ho un indice su altre colonne in quella tabella?

Ad esempio, supponiamo che nella mia Usertabella ci siano uno o due indici, la chiave primaria che è una colonna Identità / Incremento automatico e possibilmente un'altra su una colonna di chiave esterna.
Se aggiorno una colonna senza l'indice direttamente su di essa, come ad esempio il loro numero di telefono o indirizzo, questo aggiornamento viene rallentato perché ho indici su questa tabella su altre colonne in entrambe le situazioni? Le colonne che sto aggiornando non sono negli indici, quindi logicamente, gli indici non dovrebbero essere aggiornati, no? Semmai, penso che siano accelerati se uso gli indici nella clausola WHERE.


so there is no way they will not affect the indexfatta eccezione per gli indici filtrati ...
usr

Penso all'indice non coperto, non cluster come contenente i puntatori ai record (in genere nei nodi foglia dell'indice cluster della tabella). Penserei che una situazione che potrebbe causare un rallentamento durante un UPDATE (di un attributo non incluso) potrebbe essere una situazione in cui UPDATE ha causato lo spostamento del record all'interno dell'indice cluster. Non sono ancora sicuro se un movimento causerebbe la modifica del puntatore, O se il puntatore è semplicemente un valore KEY nell'indice cluster, nel qual caso il possibile aggiornamento della posizione non avrebbe importanza perché il sistema farebbe solo una ricerca KEY per ottenere il valore record.
Jmoney38,

Risposte:


6

È corretto che l'aggiornamento di una colonna non indicizzata non provochi modifiche agli indici. In un caso semplice, non ci sarebbe anche alcun impatto complessivo sul tavolo.

Se una query può utilizzare l'Indice per cercare i dati, può accelerare la ricerca, ma il comportamento esatto (a seconda del marchio SQL) potrebbe differire da altri marchi di SQL. (Uso principalmente Microsoft SQL Server.)

Naturalmente, l'aggiornamento di una colonna con un volume di dati significativamente maggiore potrebbe causare lo spostamento di righe su pagine diverse, eccetera.


1
SQL Server è menzionato nell'OP, ho aggiunto un tag, quindi penso che si possa supporre SQL Server
Tom V - Team Monica

10

Per un sistema moderno relativamente veloce, l'aggiunta di un singolo indice a una tabella OLTP sarà probabilmente praticamente non rilevabile dal punto di vista delle prestazioni per la stragrande maggioranza dei sistemi . Detto questo, non dovresti creare indici inutili e probabilmente non dovresti creare indici a colonna singola per ogni colonna di una tabella.

È corretto supporre che per molte query la presenza di indici utili comporti un notevole miglioramento della velocità.

Sebbene la tua domanda sembri riguardare il rendimento, ci sono molti altri potenziali problemi relativi all'aggiunta di indici, inclusi ma non limitati a:

  1. Il tempo necessario per creare l'indice può comportare il blocco mentre l'indice viene aggiunto alla tabella. Il blocco ha una durata molto breve e molto probabilmente non creerà un grosso problema.

  2. Le modifiche all'indice comportano l'annullamento dei piani di esecuzione per tutti i piani che fanno riferimento alla tabella sottostante. Quando questi piani di esecuzione vengono ricompilati, le prestazioni possono cambiare negativamente per alcune query.

  3. Le modifiche all'indice possono comportare la restituzione di query che non sono state restituite in precedenza. Prendi il caso di un indice filtrato che è stato usato per restituire le date contenute in un campo varchar; se il filtro ha eliminato le righe che non erano date e il filtro è stato successivamente modificato, le query che si basavano su quell'indice ora potrebbero non riuscire quando si tenta di convertire dati non di data.

  4. Un nuovo indice può causare la modifica dell'ordine di esecuzione, con il risultato di possibili deadlock in cui non si sono verificati prima.


"Il percorso del codice richiesto per un aggiornamento quando l'indice non sarà interessato deve ancora essere valutato" questo non è vero. La fase di compilazione / ottimizzazione saprà molto bene quali indici devono essere aggiornati, se presenti, e creerà il piano di conseguenza. Un'istruzione UPDATE che non modifica (dichiara nell'elenco SET) in un indice (compresi INCLUDE e colonne chiave cluster) non dovrà aggiornare tale indice e la fase di esecuzione non lo toccherà nemmeno. DELETE e INSERT ovviamente toccano tutte le colonne (logicamente) e devono aggiornare tutti gli indici.
Remus Rusanu,

@RemusRusanu ma non sarà necessario valutare se l'indice possa essere utilizzato per individuare le righe che devono essere aggiornate?
Tom V - Team Monica

@RemusRusanu - Suppongo che una volta che il QO abbia compilato un piano, non sarà più necessaria la CPU; tuttavia, per compilare il piano, è necessario farlo. Se i piani vengono compilati frequentemente, potrebbe fare una leggera differenza.
Max Vernon,

@TomV che utilizza l'indice per individuare le righe candidate da eliminare / aggiornare è un argomento completamente diverso. In tal caso, i vantaggi di individuare le righe tramite un indice dovrebbero superare qualsiasi problema relativo ai costi di manutenzione dell'indice.
Remus Rusanu,

@MaxVernon Direi che non esiste uno scenario valido di frequenti ricompilazioni di DML (UPDATE). Compro alcuni casi per ricompilazioni valide (inevitabili?) Per interrogazioni ad hoc. Ma DML? Che tipo di app potrebbe creare istruzioni UPDATE uniche e ad hoc? Ricompilazioni frequenti con DML gridano a gran voce "Parameterize me".
Remus Rusanu,

-2

Se l'operazione di aggiornamento si rivolge a una colonna non indicizzata di dimensioni fisse (come un numero intero), non dovrebbe essere lento in generale, ma rispetto a un'istruzione select, l'aggiornamento deve eventualmente essere scritto anche sul disco lento.

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.