2011-12-05 11 views
69

Ho un processo con un Select che richiede molto tempo per terminare, nell'ordine di 5-10 minuti.
Attualmente non utilizzo NOLOCK come suggerimento per il motore di database MS SQL.
Allo stesso tempo abbiamo un altro processo che esegue aggiornamenti e inserimenti nello stesso database e nelle stesse tabelle.
Il primo processo è iniziato, poco per porre fine prematuramente con un messaggioCausa di un processo che è una vittima del deadlock

SQLEXCEPTION: Transaction critico sulle risorse di blocco con un altro processo ed è stata scelta come vittima del deadlock.

Questo primo processo è in esecuzione in altri siti in condizioni identiche ma con database più piccoli e quindi l'istruzione di selezione in questione richiede un periodo di tempo molto più breve (dell'ordine di 30 secondi o giù di lì). In questi altri siti, non ottengo il messaggio deadlock in questi altri siti. Inoltre, non ho ricevuto questo messaggio sul sito che ha inizialmente il problema, ma, presumo, dal momento che il database è cresciuto, credo di aver superato qualche soglia. Ecco le mie domande:

  1. Potrebbe il tempo necessario per l'esecuzione di una transazione rendere più probabile che il processo associato venga contrassegnato come vittima di un deadlock.
  2. Se eseguo la selezione con un suggerimento NOLOCK, rimuoverà il problema?
  3. Sospetto che un campo datetime controllato come parte della clausola WHERE nell'istruzione select causi il tempo di ricerca lento. Posso creare un indice basato su questo campo? È consigliabile?
+0

Risposta parziale al punto 1: Non confondere un deadlock con un timeout. Se si è verificato un timeout, il tempo necessario per terminare una transazione potrebbe essere la causa dell'abbandono dell'altro. Inoltre, sarebbe utile sapere su quale risorsa si sta bloccando (è un indice o una tabella?). – NealB

+0

SET DEADLOCK_PRIORITY HIGH ALTER DATABASE dbname SET MULTI_USER; – gstackoverflow

risposta

84

Q1: Potrebbe il tempo necessario per una transazione per eseguire rendere il processo associato più probabilità di essere contrassegnato come una vittima deadlock.

No. Il SELECT è la vittima, perché aveva letto solo i dati, quindi la transazione è a lower cost associato con esso in modo è scelto come la vittima:

Per impostazione predefinita, il Motore di database sceglie come deadlock vittima della sessione che esegue la transazione che è meno costosa da ripristinare. In alternativa, un utente può specificare la priorità delle sessioni in una situazione di deadlock utilizzando l'istruzione SET DEADLOCK_PRIORITY. DEADLOCK_PRIORITY può essere impostato su LOW, NORMAL o HIGH o in alternativa può essere impostato su qualsiasi valore intero nell'intervallo (da -10 a 10).

Q2. Se eseguo la selezione con un suggerimento NOLOCK, rimuoverà il problema?

No. Per diversi motivi:

Q3. Sospetto che un campo datetime controllato come parte della clausola WHERE nell'istruzione select causi il tempo di ricerca lento. Posso creare un indice basato su questo campo? È consigliabile?

Probabilmente. La causa del deadlock è quasi molto probabilmente un database indicizzato male. Le query di 10 minuti sono accettabili in condizioni così strette, che sono sicuro al 100% nel tuo caso è non accettabile.

Con una confidenza del 99%, dichiaro che il deadlock è gestito da una scansione di una tabella grande in conflitto con gli aggiornamenti. Inizia catturando lo deadlock graph per analizzare la causa. Molto probabilmente dovrai ottimizzare lo schema del tuo database. Prima di apportare modifiche, leggi questo argomento Designing Indexes e gli articoli secondari.

+0

Grazie per la tua risposta completa. Credo di avere ancora una domanda però. Perché dovrei ottenere la situazione di deadlock solo in un ambiente e non in un altro. Anche se il software è lo stesso. La tua risposta suggerisce che il tempo necessario per eseguire la query Select non fa la differenza ed è il fatto che si tratta di una query Select di per sé che sta causando il fallimento del processo. Ma allora, perché solo quando la query di selezione richiede molto tempo per essere eseguita? – Elliott

+3

La lunghezza della query non fa la differenza in * scegliendo la vittima deadlock *. Fa la differenza nel causare lo stallo di almeno due fattori: 1) semplici probabilità. Più lunga è la query, maggiore è la probabilità di sovrapporre gli aggiornamenti simultanei ed eseguire deadlock. 2) una tabella più grande può utilizzare un piano di query completamente diverso, uno suscettibile di deadlock. –

9

Ecco come si è verificato effettivamente questo particolare problema di deadlock e come è stato effettivamente risolto. Questo è un database abbastanza attivo con transazioni di 130K che si verificano ogni giorno. Gli indici nelle tabelle in questo database erano originariamente in cluster. Il cliente ci ha chiesto di rendere gli indici non cluster. Non appena lo abbiamo fatto, è iniziata la fase di stallo. Quando abbiamo ristabilito gli indici come cluster, il deadlocking si è interrotto.

+12

Qualcuno può spiegare perché? (Le soluzioni magiche non sono molto utili) – OGrandeDiEnne

2

Le risposte qui valgono la pena, ma è anche necessario rivedere il codice. In particolare hanno una lettura della risposta di Polyfun qui: How to get rid of deadlock in a SQL Server 2005 and C# application?

spiega il problema di concorrenza, e in che modo l'uso di "con (UPDLOCK)" nelle query potrebbe correggere la situazione di stallo - a seconda davvero esattamente ciò che il codice sta facendo . Se il tuo codice segue questo schema, probabilmente è una soluzione migliore, prima di ricorrere a letture sporche, ecc.

Problemi correlati