Effetto del suggerimento NOLOCK nelle istruzioni SELECT


199

Immagino che la vera domanda sia:

Se non mi interessano le letture sporche, l'aggiunta del suggerimento with (NOLOCK) a un'istruzione SELECT influirà sulle prestazioni di:

  1. l'attuale istruzione SELECT
  2. altre transazioni rispetto alla tabella indicata

Esempio:

Select * 
from aTable with (NOLOCK)

3
Queste risposte SO e DBA sono un po 'più chiare su ciò che sta realmente accadendo.
Trisped

Risposte:


289

1) , una selezione con NOLOCKverrà completata più rapidamente di una selezione normale.

2) , una selezione con NOLOCKconsentirà ad altre query sulla tabella effettuata di completarsi più velocemente di una selezione normale.

Perché dovrebbe essere?

NOLOCKtipicamente (a seconda del tuo motore DB) significa che mi dai i tuoi dati, e non mi interessa in che stato si trova, e non mi preoccupo di tenerli fermi mentre leggi da esso. È tutto in una volta più veloce, meno dispendioso in termini di risorse e molto molto pericoloso.

Dovresti essere avvisato di non eseguire mai un aggiornamento o eseguire operazioni critiche sul sistema o dove è richiesta la correttezza assoluta utilizzando i dati originati da una NOLOCKlettura. È assolutamente possibile che questi dati contengano righe che sono state eliminate durante l'esecuzione della query o che sono state eliminate in altre sessioni che devono ancora essere finalizzate. È possibile che questi dati includano righe che sono state parzialmente aggiornate. È possibile che questi dati contengano record che violano i vincoli di chiave esterna. È possibile che questi dati escludano le righe che sono state aggiunte alla tabella ma che devono ancora essere impegnate.

Non hai davvero modo di sapere quale sia lo stato dei dati.

Se stai cercando di ottenere cose come un conteggio delle righe o altri dati di riepilogo in cui un margine di errore è accettabile, allora NOLOCKè un buon modo per migliorare le prestazioni di queste query ed evitare che abbiano un impatto negativo sulle prestazioni del database.

Usa sempre il NOLOCKsuggerimento con grande cautela e tratta i dati che restituisce in modo sospetto.


Grazie. Questo è quello che stavo assumendo, ma è stato messo in discussione da un collega e la mia ricerca iniziale mi ha fatto interrogare da solo. La documentazione di SQLServer 2005 afferma che con NOLOCK è lo schema di blocco predefinito per tutte le istruzioni selezionate! Immagino quindi che i miei suggerimenti sarebbero ridondanti in ...
Bob Probst,

2
... 2005 e non hanno alcun effetto. Stiamo eseguendo 2000 in questo momento (grazie al nostro fornitore) e non ci sono dichiarazioni simili nella documentazione.
Bob Probst,

4
Il tuo amico deve leggere la documentazione. Suggerimento tabella (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx
DBA di Pittsburgh,

9
Nota a margine: se questo fosse vero, sarebbe il caos assoluto.
Pittsburgh DBA,

1
I punti 1 e 2 devono essere limitati a 1) "... quando un'azione di inserimento / aggiornamento / eliminazione è in sospeso sulla tabella ." e 2) "... consentirà di inserire / aggiornare / eliminare le query contro ...". Vorrei (preferenza personale) cambiare le istanze di "più veloce" in "prima" poiché la differenza è in attesa di un altro processo completato.
Trisped

61

NOLOCK rende la maggior parte delle istruzioni SELECT più veloci, a causa della mancanza di blocchi condivisi. Inoltre, la mancanza di rilascio dei blocchi significa che il tuo SELECT non sarà impedito agli scrittori.

NOLOCK è funzionalmente equivalente a un livello di isolamento di READ UNCOMMITTED. La differenza principale è che puoi usare NOLOCK su alcuni tavoli ma non su altri, se lo desideri. Se si prevede di utilizzare NOLOCK su tutte le tabelle in una query complessa, l'utilizzo di SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED è più semplice, poiché non è necessario applicare il suggerimento a ogni tabella.

Ecco informazioni su tutti i livelli di isolamento a tua disposizione, nonché suggerimenti sulla tabella.

IMPOSTARE LIVELLO DI ISOLAMENTO DELLE TRANSAZIONI

Suggerimento tabella (Transact-SQL)


2
Sono d'accordo, ma non completamente; è importante sottolineare che un suggerimento NO LOCK / READ UNCOMMITTED non migliora effettivamente la velocità della query, ma lo fa sembrare più veloce perché non deve attendere il completamento delle query precedenti. Quindi, davvero, la query SEMBRA più veloce, piuttosto che È più veloce (penso).
Möoz,

1
@BorhanMooz Bene, c'è il risparmio di non dover richiedere blocchi dal gestore dei blocchi. Anche se non ci sono altre query in attesa, questo ha un costo e un sovraccarico di memoria.
Pittsburgh DBA,

1
Ne stavo discutendo con alcuni dei miei compagni di lavoro. A quanto mi risulta, una query che utilizza un suggerimento WITH (NOLOCK) richiede comunque il raggiungimento di un blocco Schema-Shared ( mssqltips.com/sqlservertip/2470/… ).
Möoz,

1
Sì, ma non migliaia di blocchi condivisi su pagine o estensioni. Un blocco dello schema è UN blocco, non MIGLIAIA. Se vogliamo essere pedanti, possiamo continuare a discuterne, ma sì, ci sarà una quantità minima di overhead di blocco. I risparmi sono significativi. Fai i conti con questo: msdn.microsoft.com/en-us/library/aa337559(v=sql.100).aspx
Pittsburgh DBA


6

Sarà più veloce perché non deve attendere i blocchi


Quanto più veloce? Potresti fornire dei numeri di miglioramento della velocità?
Eugeniu Torica,

5
"Quanto" dipende da cosa stai facendo specificamente con i tuoi dati e da quanto tempo in genere devi attendere l'acquisizione di un blocco.
StingyJack,

L'unico benchmark corretto è quello che crei e gestisci da solo. Ciò che tutti ti dicono è buono come "il controllo è nella posta". Ho dimostrato molte volte miti e ipotesi errate eseguendo i miei parametri di riferimento.
TravisO,

^ @TravisO - è completamente corretto. Ho fatto eseguire NOLOCK più lentamente alcune volte. Non sono del tutto sicuro del perché, ma lo sto usando durante la risoluzione dei problemi e non voglio influire negativamente (in modo eccessivo) sulla produzione
StingyJack,

2
  • La risposta è se la query viene eseguita più volte contemporaneamente, poiché ogni transazione non dovrà attendere il completamento delle altre. Tuttavia, se la query viene eseguita una sola volta, la risposta è No.

  • . Esiste una probabilità significativa che un uso attento di WITH (NOLOCK) acceleri il database in generale. Significa che altre transazioni non dovranno attendere il completamento di questa istruzione SELECT, ma d'altra parte altre transazioni rallenteranno poiché ora condividono il tempo di elaborazione con una nuova transazione.

Fare attenzione a utilizzare soloWITH (NOLOCK) nelle istruzioni SELECT su tabelle che hanno un indice cluster.

WITH (NOLOCK) viene spesso sfruttato come un modo magico per accelerare le transazioni di lettura del database.

Il set di risultati può contenere righe non ancora impegnate, che spesso vengono successivamente ripristinate.

Se WITH (NOLOCK) viene applicato a una tabella che ha un indice non cluster, gli indici di riga possono essere modificati da altre transazioni mentre i dati di riga vengono trasmessi in streaming nella tabella dei risultati. Ciò significa che nel set di risultati possono mancare righe o visualizzare la stessa riga più volte.

READ COMMITTED aggiunge un ulteriore problema in cui i dati sono danneggiati all'interno di una singola colonna in cui più utenti cambiano la stessa cella contemporaneamente.

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.