2 Stimmen

SQL Server-Tabellensperren in langen Abfragen - Lösung: NoLock?

Ein Bericht in meiner Anwendung führt eine Abfrage aus, die zwischen 5 und 15 Sekunden benötigt (abhängig von der Anzahl der Zeilen, die zurückgegeben werden). Die Abfrage hat 8 Verknüpfungen zu fast allen Haupttabellen meiner Anwendung (Kunden, Verkäufe, Einheiten usw.).

Ein kleines Tool zeigt mir, dass in dieser Zeit alle diese 8 Tabellen mit einer gemeinsamen Tabellensperre gesperrt sind. Das bedeutet, dass in dieser Zeit keine Aktualisierungsoperationen durchgeführt werden können.

Eine Lösung von einem Freund ist, jede Verknüpfung in der Abfrage, die nicht zwingend 100% korrekte Daten haben muss (dirty read), mit einem NoLock zu versehen, so dass nur 1 dieser 8 Tabellen komplett gesperrt wird. Ist das eine gute Lösung? Für einen Bericht, bei dem 99 % der Daten aus einer Tabelle stammen, sollten die weniger wichtigen Tabellen nicht gesperrt werden?

4voto

Quassnoi Punkte 396418

NOLOCK bedeutet, dass überhaupt keine Schlösser angebracht werden.

Ihre Abfrage kann Teile von Daten zurückgeben, die vor UPDATE und Anteile ab nach UPDATE in einer einzigen Abfrage .

Zum Beispiel eine Abbuchung ohne Kredit und solche Sachen.

Ich habe zum Beispiel gerade diese Abfrage für eine große Tabelle ausgeführt:

SELECT  SUM(LEN(name))
FROM    master WITH (NOLOCK)
OPTION (MAXDOP 1)

---
18874367

Alle name haben eine Länge von 1 .

Dann habe ich die Abfrage erneut ausgeführt und mitten in der Abfrage die Tabelle aktualisiert:

UPDATE  master
SET     name = 'tt'
WHERE   id <= 10000

SELECT  SUM(LEN(name))
FROM    master WITH (NOLOCK)
OPTION (MAXDOP 1)

---
18874944

Wie wir sehen können, bemerkte diese Abfrage 577 Zeilen als aktualisiert (Länge 2 ), alle anderen Zeilen als nicht aktualisiert (Länge 1 ).

SELECT  SUM(LEN(name))
FROM    master WITH (NOLOCK)
OPTION (MAXDOP 1)

---
18884367

Und diese Abfrage, die direkt nach Beendigung der vorherigen Abfrage ausgeführt wird, sieht alle Aktualisierungen.

4voto

Robin Day Punkte 97662

Versuchen Sie, READ COMMITTED SNAPSHOT anstelle von NOLOCK zu verwenden. Das bedeutet, dass die Daten zwar "alt" sein können, aber niemals schmutzig werden.

0voto

Joel Coehoorn Punkte 377088

Das ist in Ordnung, solange Sie diesen Satz sehr stark betonen:

die nicht zwingend 100% korrekte Daten enthalten müssen (dirty read)

Sie sollten also wahrscheinlich keinen Nolock-Hinweis zu Ihrer Verkaufstabelle hinzufügen, aber Ihre Kundentabelle (die wahrscheinlich weniger Änderungen erfährt) ist vielleicht in Ordnung. Selbst dort verwenden Sie wahrscheinlich nicht so viele Kundendatensätze in einer einzigen Abfrage, aber wenn sich einer ändert, könnte das ein großes Problem darstellen. Daher sollten Sie die rowlock Hinweis für diese Tabelle.

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