Auswirkung des NOLOCK-Hinweises in SELECT-Anweisungen


199

Ich denke die eigentliche Frage ist:

Wenn mir Dirty Reads egal sind, wirkt sich das Hinzufügen des with- Hinweises (NOLOCK) zu einer SELECT-Anweisung auf die Leistung von:

  1. die aktuelle SELECT-Anweisung
  2. andere Transaktionen gegen die angegebene Tabelle

Beispiel:

Select * 
from aTable with (NOLOCK)

3
Diese SO- und DBA- Antworten sind etwas klarer darüber, was tatsächlich passiert.
Trisped

Antworten:


289

1) Ja , eine Auswahl mit NOLOCKwird schneller abgeschlossen als eine normale Auswahl.

2) Ja , mit einer Auswahl mit NOLOCKkönnen andere Abfragen für die betroffene Tabelle schneller als mit einer normalen Auswahl abgeschlossen werden.

Warum sollte das so sein?

NOLOCKIn der Regel (abhängig von Ihrer DB-Engine) bedeutet dies, dass Sie mir Ihre Daten geben. Es ist mir egal, in welchem ​​Zustand sie sich befinden, und Sie müssen sie nicht stillhalten, während Sie daraus lesen. Es ist auf einmal schneller, weniger ressourcenintensiv und sehr, sehr gefährlich.

Sie sollten gewarnt werden, niemals ein Update von oder etwas Systemkritisches durchzuführen oder wenn absolute Korrektheit unter Verwendung von Daten erforderlich ist, die aus einem NOLOCKLesevorgang stammen. Es ist absolut möglich, dass diese Daten Zeilen enthalten, die während der Ausführung der Abfrage gelöscht wurden oder die in anderen Sitzungen gelöscht wurden, die noch abgeschlossen werden müssen. Möglicherweise enthalten diese Daten Zeilen, die teilweise aktualisiert wurden. Möglicherweise enthalten diese Daten Datensätze, die gegen Fremdschlüsseleinschränkungen verstoßen. Es ist möglich, dass diese Daten Zeilen ausschließen, die der Tabelle hinzugefügt wurden, aber noch festgeschrieben werden müssen.

Sie haben wirklich keine Möglichkeit zu wissen, wie der Status der Daten ist.

Wenn Sie versuchen, Dinge wie eine Zeilenanzahl oder andere Zusammenfassungsdaten zu erhalten, bei denen eine gewisse Fehlerquote akzeptabel ist, dann NOLOCK ist, können Sie die Leistung dieser Abfragen steigern und vermeiden, dass sie sich negativ auf die Datenbankleistung auswirken.

Verwenden Sie den NOLOCKHinweis immer mit großer Vorsicht und behandeln Sie alle zurückgegebenen Daten verdächtig.


Vielen Dank. Dies ist, was ich angenommen habe, aber von einem Kollegen darüber befragt wurde, und meine ersten Nachforschungen haben mich dazu gebracht, mich selbst in Frage zu stellen. In der Dokumentation zu SQLServer 2005 heißt es, dass NOLOCK das Standard-Sperrschema für alle select-Anweisungen ist! Ich würde dann vermuten, dass meine Hinweise in ...
Bob Probst

2
... 2005 und keine Wirkung haben. Wir führen derzeit 2000 aus (dank unseres Anbieters) und es gibt keine ähnliche Aussage in der Dokumentation.
Bob Probst

4
Ihr Freund muss die Dokumentation lesen. Tabellenhinweis (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx
Pittsburgh DBA

9
Randnotiz: Wenn dies wahr wäre, wäre es absolutes Chaos.
Pittsburgh DBA

1
Die Punkte 1 und 2 müssen auf 1) "... beschränkt werden, wenn eine Einfüge- / Aktualisierungs- / Löschaktion für die Tabelle ansteht ." und 2) "... ermöglicht das Einfügen / Aktualisieren / Löschen von Abfragen gegen ...". Ich würde (persönliche Präferenz) Instanzen von "schneller" in "früher" ändern, da der Unterschied darauf wartet, dass ein anderer Prozess abgeschlossen ist.
Trisped

61

NOLOCK macht die meisten SELECT-Anweisungen schneller, da keine gemeinsamen Sperren vorhanden sind. Das Fehlen der Ausgabe der Sperren bedeutet auch, dass die Autoren nicht durch Ihre SELECT behindert werden.

NOLOCK entspricht funktional einer Isolationsstufe von READ UNCOMMITTED. Der Hauptunterschied besteht darin, dass Sie NOLOCK für einige Tabellen verwenden können, für andere jedoch nicht, wenn Sie dies wünschen. Wenn Sie NOLOCK für alle Tabellen in einer komplexen Abfrage verwenden möchten, ist die Verwendung von SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED einfacher, da Sie den Hinweis nicht auf jede Tabelle anwenden müssen.

Hier finden Sie Informationen zu allen Isolationsstufen, die Ihnen zur Verfügung stehen, sowie Tabellenhinweise.

SET TRANSACTION ISOLATION LEVEL

Tabellenhinweis (Transact-SQL)


2
Ich stimme zu, aber nicht vollständig; Es ist wichtig darauf hinzuweisen, dass ein NO LOCK / READ UNCOMMITTED-Hinweis die Geschwindigkeit der Abfrage nicht verbessert, sie jedoch schneller erscheinen lässt, da sie nicht auf den Abschluss vorheriger Abfragen warten muss. Die Abfrage scheint also schneller zu sein als schneller (glaube ich).
Möoz

1
@BorhanMooz Nun, es gibt die Einsparungen, wenn Sie keine Sperren vom Schlossmanager anfordern müssen. Selbst wenn keine anderen Abfragen warten, hat dies Kosten und einen Speicheraufwand.
Pittsburgh DBA

1
Ich habe das mit einigen meiner Kollegen besprochen. Soweit ich weiß, muss für eine Abfrage mit einem WITH (NOLOCK) -Hinweis immer noch eine Schema-Shared-Sperre erreicht werden ( mssqltips.com/sqlservertip/2470/… ).
Möoz

1
Ja, aber nicht Tausende von freigegebenen Sperren für Seiten oder Bereiche. Eine Schemasperre ist EINE Sperre, nicht TAUSENDE. Wenn wir pedantisch sein wollen, können wir darüber weiter diskutieren, aber ja, es wird einen minimalen Lock-Overhead geben. Die Einsparungen sind erheblich. Rechnen Sie
Pittsburgh DBA


6

Es wird schneller sein, weil es nicht auf Sperren warten muss


Wie viel schneller? Könnten Sie Zahlen zur Geschwindigkeitsverbesserung angeben?
Eugeniu Torica

5
"Wie viel" hängt davon ab, was Sie speziell mit Ihren Daten tun und wie lange Sie normalerweise auf eine Sperrenerfassung warten müssen.
StingyJack

Der einzig richtige Benchmark ist der, den Sie selbst erstellen und ausführen. Was jeder Ihnen sagt, ist so gut wie "der Scheck ist in der Post". Ich habe viele Mythen und Annahmen oft als falsch erwiesen, indem ich meine eigenen Benchmarks durchgeführt habe.
TravisO

^ @TravisO - ist völlig korrekt. Ich habe NOLOCK einige Male langsamer ausführen lassen. Ich bin mir nicht ganz sicher warum, aber ich benutze das bei der Fehlerbehebung und möchte die Produktion nicht negativ (über) beeinflussen
StingyJack

2
  • Die Antwort lautet Ja, wenn die Abfrage mehrmals gleichzeitig ausgeführt wird, da jede Transaktion nicht auf den Abschluss der anderen warten muss. Wenn die Abfrage jedoch einmal alleine ausgeführt wird, lautet die Antwort Nein.

  • Ja . Es besteht eine erhebliche Wahrscheinlichkeit, dass die sorgfältige Verwendung von WITH (NOLOCK) Ihre Datenbank insgesamt beschleunigt. Dies bedeutet, dass andere Transaktionen nicht auf den Abschluss dieser SELECT-Anweisung warten müssen. Andererseits werden andere Transaktionen langsamer, da sie jetzt ihre Verarbeitungszeit mit einer neuen Transaktion teilen.

Achten Sie darauf, nur die Verwendung WITH (NOLOCK)in SELECT - Anweisungen auf Tabellen , die einen Clustered - Index haben.

WITH (NOLOCK) wird häufig als magische Methode zur Beschleunigung von Datenbanklesetransaktionen genutzt.

Die Ergebnismenge kann Zeilen enthalten, die noch nicht festgeschrieben wurden und häufig später zurückgesetzt werden.

Wenn WITH (NOLOCK) auf eine Tabelle mit einem nicht gruppierten Index angewendet wird, können Zeilenindizes durch andere Transaktionen geändert werden, während die Zeilendaten in die Ergebnistabelle gestreamt werden. Dies bedeutet, dass in der Ergebnismenge möglicherweise Zeilen fehlen oder dieselbe Zeile mehrmals angezeigt wird.

READ COMMITTED fügt ein zusätzliches Problem hinzu, bei dem Daten in einer einzelnen Spalte beschädigt werden, in der mehrere Benutzer dieselbe Zelle gleichzeitig ändern.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.