2011-10-05 1 views
7

Sono in esecuzione una dichiarazione di cancellazione:11 secondi per eliminare 240 righe in SQL Server

DELETE FROM TransactionEntries 
WHERE SessionGUID = @SessionGUID 

Il piano di esecuzione effettiva della cancellazione è:

Execution Tree 
-------------- 
Clustered Index Delete(
    OBJECT:([GrobManagementSystemLive].[dbo].[TransactionEntries].IX_TransactionEntries_SessionGUIDTransactionGUID]), 
    WHERE:([TransactionEntries].[SessionGUID]=[@SessionGUID]) 
) 

La tabella è di tipo cluster da SessionGUID, così le 240 file sono fisicamente insieme.

La tabella non ha trigger su di esso.

L'operazione richiede:

  • Durata: 11821 ms
  • CPU: 297
  • Letture: 14340
  • scrive: 1707

La tabella contiene 11 indici:

  • 1 indice cluster (SessionGUID)
  • 1 unico (chiave primaria) Indice
  • 9 altri non univoci, indici non cluster

Come posso capire perché questa operazione delete sta eseguendo 14,340 legge, e impiega 11 secondi?

  • il Avg. Disk Read Queue Length raggiunge 0.8
  • il Avg. Disk sec/Read non supera mai 4ms
  • il Avg. Disk Write Queue Length raggiunge 0.04
  • il Avg. Disk sec/Write non supera mai 4ms

Quali sono gli altri legge per? Il piano di esecuzione non fornisce alcuna indicazione di che cosa sta leggendo.


Aggiornamento:

EXECUTE sp_spaceused TransactionEntries 

TransactionEntries 
    Rows  6,696,199 
    Data:  1,626,496 KB (249 bytes per row) 
    Indexes: 7,303,848 KB (1117 bytes per row) 
    Unused:  91,648 KB  
      ============ 
    Reserved: 9,021,992 KB (1380 bytes per row) 

Con 1,380 byte per riga, e 240 righe, che è 340 kB da cancellare.

Contro intuitivo che può essere così difficile per 340 kB.

aggiornare due: frammentazione

Name       Scan Density Logical Fragmentation 
============================= ============ ===================== 
IX_TransactionEntries_Tran... 12.834  48.392 
IX_TransactionEntries_Curr... 15.419  41.239 
IX_TransactionEntries_Tran... 12.875  48.372 
TransactionEntries17   98.081   0.0049325 
TransactionEntries5   12.960  48.180 
PK_TransactionEntries   12.869  48.376 
TransactionEntries18   12.886  48.480 
IX_TranasctionEntries_CDR... 12.799  49.157 
IX_TransactionEntries_CDR... 12.969  48.103 
IX_TransactionEntries_Tra... 13.181  47.127 

i deframmentare la TransactionEntries17

DBCC INDEXDEFRAG (0, 'TransactionEntries', 'TransactionEntries17') 

dal INDEXDEFRAG è un "funzionamento online" (vale a dire che detiene solo IS blocchi condivisi Intent). Stavo per deframmentare manualmente gli altri fino a quando le operazioni commerciali non hanno chiamato, dicendo che il sistema è morto - e sono passati a fare tutto su carta.

Cosa dici tu; La frammentazione del 50% e la densità di scansione solo del 12% causano prestazioni di scansione dell'indice orribili?

+2

La mia ipotesi è che sono state apportate le modifiche a quegli altri 10 indici. –

+1

Giusto per aggiungere al punto di Joe, anche il tasto CI viene usato come localizzatore di riga in tutti gli NCI. –

risposta

1

Dopo aver sbattuto la testa sul problema di prestazioni molti-a-SQL, la mia procedura operativa standard per qualcosa di simile è quello di:

  1. Eseguire il backup dei dati
  2. eliminare uno degli indici sul tavolo domanda
  3. Misurare l'operazione
  4. Restore DB
  5. Ripetere w/# 2 fino a 3 # mostra un drastico cambiamento. Questo è probabilmente il tuo colpevole.
5

Come @JoeStefanelli indica nei commenti, sono gli indici extra non in cluster.

Si stanno eliminando 240 righe dalla tabella.

Questo corrisponde a righe di indice, 240 delle quali includono tutti i campi nella tabella.

A seconda di quanto sono ampi e di quanti campi inclusi hai, questo potrebbe equivalere a tutte le attività di lettura extra che stai vedendo.

Le righe dell'indice non raggruppate saranno sicuramente NON raggruppate insieme su disco, il che aumenterà i ritardi.

+0

In passato su alcune tabelle piuttosto grandi ho implementato un processo per eliminare tutti gli indici non in cluster, eseguire le eliminazioni e aggiungerle nuovamente. In realtà era più veloce delle eliminazioni senza farlo. E 'stato anche un approccio di cauzione e nastro conduttore che non consiglierei di fare di nuovo (questo era molti anni fa). – Wil

+1

@Wil - Puoi farlo e dovrebbe accelerarlo, ma è disordinato e non la migliore pratica. – JNK

+0

Notare che gli indici non raggruppati non sono raggruppati insieme è un buon punto. Ciò significa che richiedono una scansione dell'indice. –

1

Penso che l'indicizzazione potrebbe essere il colpevole più probabile ma volevo lanciare un'altra possibilità. Hai menzionato nessun trigger, ma ci sono tabelle che hanno una relazione di chiave esterna con questa tabella? Dovrebbero essere controllati per assicurarsi che non ci siano record in essi e se hai attivato l'eliminazione a cascata, quei record dovrebbero essere cancellati.

+0

Non ci sono tabelle per la chiave * per * questa tabella.Quindi il piano di esecuzione in quelle situazioni comporta ricerche/scansioni del tavolo esterno. Il piano di esecuzione in questo caso non mostra attività su altre tabelle; che conferma che non esistono ricerche di integrità dei vincoli di chiave esterna. Comunque è un buon punto. –