215 Stimmen

Wirkung des NOLOCK-Hinweises in SELECT-Anweisungen

Ich denke, die eigentliche Frage ist:

Wenn ich mich nicht um Dirty Reads kümmere, wird das Hinzufügen der mit (NOLOCK) Hinweis auf eine SELECT-Anweisung die Leistung von beeinträchtigen:

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

Exemple :

Select * 
from aTable with (NOLOCK)

4 Stimmen

Diese SO y DBA sind die Antworten ein wenig klarer, was tatsächlich passiert.

313voto

tom.dietrich Punkte 8129

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

2) Ja , eine Auswahl mit NOLOCK ermöglicht es anderen Abfragen gegen die betroffene Tabelle, schneller abzuschließen als ein normaler Select.

Warum sollte das so sein?

NOLOCK bedeutet in der Regel (je nach DB-Engine), dass Sie mir Ihre Daten geben, und es ist mir egal, in welchem Zustand sie sind, und Sie brauchen sie nicht festzuhalten, während Sie daraus lesen. Das ist gleichzeitig schneller, weniger ressourcenintensiv und sehr, sehr gefährlich.

Sie sollten gewarnt werden, niemals eine Aktualisierung von oder etwas Systemkritisches durchzuführen, oder wenn absolute Korrektheit erforderlich ist, Daten zu verwenden, die von einer NOLOCK lesen. Es ist durchaus möglich, dass diese Daten Zeilen enthalten, die während der Ausführung der Abfrage gelöscht wurden oder die in anderen, noch nicht abgeschlossenen Sitzungen gelöscht wurden. Es ist möglich, dass diese Daten Zeilen enthalten, die teilweise aktualisiert worden sind. Es ist möglich, dass diese Daten Datensätze enthalten, die Fremdschlüssel-Beschränkungen verletzen. Es ist möglich, dass diese Daten Zeilen ausschließen, die der Tabelle hinzugefügt wurden, aber noch nicht bestätigt wurden.

Sie haben wirklich keine Möglichkeit, den Stand der Daten zu erfahren.

Wenn Sie versuchen, Dinge wie eine Zeilenzahl oder andere zusammenfassende Daten zu erhalten, bei denen eine gewisse Fehlerspanne akzeptabel ist, dann NOLOCK ist eine gute Möglichkeit, die Leistung für diese Abfragen zu steigern und zu vermeiden, dass sie sich negativ auf die Datenbankleistung auswirken.

Verwenden Sie immer die NOLOCK Hinweis mit großer Vorsicht zu behandeln und alle Daten, die er zurückgibt, verdächtig zu behandeln.

0 Stimmen

Danke! Davon bin ich ausgegangen, aber ich wurde von einem Kollegen dazu befragt, und meine ersten Nachforschungen haben mich selbst in Frage gestellt. In der SQLServer 2005-Dokumentation steht, dass NOLOCK das Standardsperrschema für alle Select-Anweisungen ist! Ich würde dann vermuten, dass meine Hinweise überflüssig wären in ...

2 Stimmen

... 2005 und keine Auswirkungen haben. Wir verwenden derzeit 2000 (dank unseres Anbieters) und in der Dokumentation findet sich keine ähnliche Aussage.

5 Stimmen

Ihr Freund muss die Dokumentation lesen. Tabellen-Hinweis (Transact-SQL) msdn.microsoft.com/de-us/library/ms187373(SQL.90).aspx

65voto

Pittsburgh DBA Punkte 6492

NOLOCK macht die meisten SELECT-Anweisungen schneller, da es keine gemeinsamen Sperren gibt. Außerdem bedeutet die fehlende Ausgabe der Sperren, dass die Schreiber nicht durch Ihr SELECT behindert werden.

NOLOCK ist funktionell gleichbedeutend mit einem Isolationslevel von READ UNCOMMITTED. Der Hauptunterschied besteht darin, dass Sie NOLOCK auf einige Tabellen anwenden können, aber nicht auf andere, wenn Sie dies wünschen. Wenn Sie vorhaben, NOLOCK auf alle Tabellen in einer komplexen Abfrage anzuwenden, ist die Verwendung von SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED einfacher, da Sie den Hint nicht auf jede Tabelle anwenden müssen.

Hier finden Sie Informationen zu allen Ihnen zur Verfügung stehenden Isolationsstufen sowie Hinweise zur Tabelle.

TRANSAKTIONSISOLATIONSEBENE FESTLEGEN

Tabellen-Hinweis (Transact-SQL)

3 Stimmen

Ich stimme zu, aber nicht ganz; es ist wichtig, darauf hinzuweisen, dass ein NO LOCK / READ UNCOMMITTED-Hinweis die Geschwindigkeit der Abfrage nicht wirklich verbessert, sondern eher den Anschein erweckt, dass sie schneller ist, weil sie nicht auf die Beendigung früherer Abfragen warten muss. Die Abfrage scheint also tatsächlich schneller zu sein, anstatt schneller zu sein (denke ich).

1 Stimmen

@BorhanMooz Nun, es gibt die Ersparnis, dass man keine Sperren vom Lock Manager anfordern muss. Selbst wenn keine anderen Abfragen warten, hat dies Kosten und einen Speicher-Overhead.

1 Stimmen

Ich habe dies mit einigen meiner Arbeitskollegen diskutiert. So wie ich es verstehe, erfordert eine Abfrage, die einen WITH(NOLOCK)-Hinweis verwendet, immer noch eine Schema-Shared-Sperre, um erreicht zu werden ( mssqltips.com/sqlservertip/2470/ ).

14voto

Zusätzlich zu dem oben Gesagten sollten Sie sich darüber im Klaren sein, dass nolock tatsächlich das Risiko birgt, dass Sie no Abrufen von Zeilen, die übertragen wurden antes de Sie wählen.

Siehe http://blogs.msdn.com/sqlcat/archive/2007/02/01/previously-committed-rows-might-be-missed-if-nolock-hint-is-used.aspx

7voto

StingyJack Punkte 18514

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

1 Stimmen

Wie viel schneller? Können Sie Zahlen zur Geschwindigkeitssteigerung nennen?

6 Stimmen

"Wie viel" hängt davon ab, was Sie konkret mit Ihren Daten machen und wie lange Sie normalerweise auf die Erfassung einer Sperre warten müssen.

1 Stimmen

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

2voto

WonderWorker Punkte 7910
  • Die Antwort lautet Ja wenn die Abfrage mehrere Male gleichzeitig ausgeführt wird, da jede Transaktion nicht auf den Abschluss der anderen warten muss. Wenn die Abfrage jedoch einmalig ausgeführt wird, lautet die Antwort Nein.

  • Ja . Es besteht eine hohe Wahrscheinlichkeit, dass die sorgfältige Verwendung von WITH(NOLOCK) Ihre Datenbank insgesamt beschleunigt. Das bedeutet, dass andere Transaktionen nicht auf die Beendigung dieser SELECT-Anweisung warten müssen, aber auf der anderen Seite werden andere Transaktionen langsamer, da sie nun ihre Verarbeitungszeit mit einer neuen Transaktion teilen müssen.

Achten Sie darauf, dass sólo verwenden. WITH (NOLOCK) in SELECT-Anweisungen auf Tabellen, die einen geclusterten Index haben.

WITH(NOLOCK) wird oft als magischer Weg zur Beschleunigung von Datenbanktransaktionen ausgenutzt.

Die Ergebnismenge kann Zeilen enthalten, die noch nicht festgeschrieben wurden und oft später wieder zurückgenommen werden.

Wenn WITH(NOLOCK) auf eine Tabelle angewendet wird, die einen nicht geclusterten Index hat, können Zeilenindizes von anderen Transaktionen geändert werden, während die Zeilendaten in die Ergebnistabelle gestreamt werden. Dies bedeutet, dass in der Ergebnismenge Zeilen fehlen können oder dieselbe Zeile mehrfach angezeigt wird.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X