Wpływ podpowiedzi NOLOCK w instrukcjach SELECT

199

Chyba prawdziwe pytanie brzmi:

Jeśli nie przejmuję się brudnymi odczytami, dodanie wskazówki with (NOLOCK) do instrukcji SELECT wpłynie na wydajność:

  1. bieżąca instrukcja SELECT
  2. inne transakcje na podstawie podanej tabeli

Przykład:

Select * 
from aTable with (NOLOCK)
Bob Probst
źródło
3
Te odpowiedzi SO i DBA są nieco jaśniejsze, co faktycznie się dzieje.
Trisped 21.01.16

Odpowiedzi:

289

1) Tak , wybór z NOLOCKzakończy się szybciej niż normalny wybór.

2) Tak , wybór za pomocą NOLOCKpozwoli na wykonanie innych zapytań względem wykonanej tabeli szybciej niż normalny wybór.

Dlaczego miałoby to być?

NOLOCKzazwyczaj (w zależności od silnika DB) oznacza, że ​​podaj mi swoje dane, a ja nie dbam o to, w jakim jest stanie, i nie zawracam sobie głowy trzymaniem ich w miejscu podczas czytania. Wszystko to naraz jest szybsze, mniej zasobochłonne i bardzo bardzo niebezpieczne.

Powinieneś zostać ostrzeżony, aby nigdy nie przeprowadzać aktualizacji ani nie wykonywać niczego krytycznego dla systemu lub gdy wymagana jest absolutna poprawność przy użyciu danych pochodzących z NOLOCKodczytu. Jest absolutnie możliwe, że dane te zawierają wiersze, które zostały usunięte podczas uruchamiania zapytania lub zostały usunięte w innych sesjach, które jeszcze nie zostały sfinalizowane. Możliwe, że dane te zawierają częściowo zaktualizowane wiersze. Możliwe, że dane te zawierają rekordy, które naruszają ograniczenia klucza obcego. Możliwe, że dane te nie obejmują wierszy, które zostały dodane do tabeli, ale nie zostały jeszcze zatwierdzone.

Naprawdę nie masz sposobu, aby dowiedzieć się, jaki jest stan danych.

Jeśli próbujesz uzyskać takie dane, jak liczba wierszy lub inne dane podsumowujące, w których dopuszczalny jest pewien margines błędu, NOLOCKto dobry sposób na zwiększenie wydajności tych zapytań i uniknięcie negatywnego wpływu na wydajność bazy danych.

Zawsze używaj NOLOCKpodpowiedzi z wielką ostrożnością i traktuj wszelkie dane, które zwraca podejrzliwie.

tom.dietrich
źródło
Dzięki. Tak właśnie zakładam, ale zostałem o to zapytany przez kolegę, a moje wstępne badania sprawiły, że zadałem sobie pytanie. Dokumentacja SQLServer 2005 mówi, że NOLOCK jest domyślnym schematem blokowania wszystkich instrukcji select! Domyślam się wtedy, że moje wskazówki byłyby zbędne w ...
Bob Probst
2
... 2005 i nie mają żadnego efektu. Obecnie działamy w 2000 roku (dzięki naszemu dostawcy) i nie ma podobnego stwierdzenia w dokumentacji.
Bob Probst
4
Twój przyjaciel musi przeczytać dokumentację. Wskazówka do tabeli (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx
Pittsburgh DBA
9
Uwaga dodatkowa: gdyby to była prawda, byłby to absolutny chaos.
Pittsburgh DBA,
1
Punkty 1 i 2 należy ograniczyć do 1) „... gdy na stole oczekuje się operacji wstawiania / aktualizacji / usuwania ”. oraz 2) „... pozwoli wstawiać / aktualizować / usuwać zapytania dotyczące ...”. Zmieniłbym (preferencje osobiste) instancje „szybciej” na „wcześniej”, ponieważ różnica czeka na zakończenie innego procesu.
Trisped 21.01.16
61

NOLOCK sprawia, że ​​większość instrukcji SELECT jest szybsza z powodu braku współdzielonych blokad. Ponadto brak wydawania blokad oznacza, że ​​Twój SELECT nie będzie utrudniał pisarzom.

NOLOCK jest funkcjonalnie równoważny poziomowi izolacji ODCZYTAJ NIEZGODNIE. Główną różnicą jest to, że możesz używać NOLOCK na niektórych stołach, ale nie na innych, jeśli chcesz. Jeśli planujesz używać NOLOCK na wszystkich tabelach w złożonym zapytaniu, wówczas użycie USTAW POZIOMU ​​IZOLACJI ODCZYTAJ NIEZGODNE jest łatwiejsze, ponieważ nie musisz stosować podpowiedzi do każdej tabeli.

Oto informacje o wszystkich poziomach izolacji, jakie masz do dyspozycji, a także wskazówki dotyczące tabel.

USTAW POZIOM IZOLACJI TRANSAKCJI

Wskazówka do tabeli (Transact-SQL)

Pittsburgh DBA
źródło
2
Zgadzam się, ale nie do końca; ważne jest, aby zauważyć, że podpowiedź BRAK BLOKADY / CZYTANIA NIEZGODNEGO Z NAMI nie poprawia w rzeczywistości szybkości zapytania, a tym bardziej sprawia, że ​​pojawia się on szybciej, ponieważ nie musi czekać na zakończenie poprzednich zapytań. Tak naprawdę zapytanie SEEMS jest szybsze niż IS szybsze (tak myślę).
Möoz,
1
@ BorhanMooz Cóż, oszczędności wynikają z braku konieczności żądania blokady od menedżera blokady. Nawet jeśli nie czekają inne zapytania, wiąże się to z dodatkowymi kosztami i pamięcią.
Pittsburgh DBA,
1
Rozmawiałem o tym z niektórymi kolegami z pracy. Jak rozumiem, zapytanie wykorzystujące wskazówkę WITH (NOLOCK) nadal wymaga uzyskania blokady współużytkowanej przez schemat ( mssqltips.com/sqlservertip/2470/… ).
Möoz,
1
Tak, ale nie tysiące udostępnionych blokad na stronach lub zakresach. Blokada schematu jest JEDNĄ blokadą, a NIE TYSIĄCAMI. Jeśli chcemy być pedantyczni, możemy kontynuować debatę na ten temat, ale tak, narzut będzie minimalny. Oszczędności są znaczne. Zrób matematykę na tym: msdn.microsoft.com/en-us/library/aa337559(v=sql.100).aspx
Pittsburgh DBA
6

Będzie szybciej, ponieważ nie musi czekać na zamki

StingyJack
źródło
O ile szybciej? Czy możesz podać jakieś numery dotyczące poprawy prędkości?
Eugeniu Torica,
5
„Ile” zależy od tego, co konkretnie robisz ze swoimi danymi i jak długo zwykle musisz czekać na przejęcie blokady.
StingyJack
Jedynym prawidłowym testem porównawczym jest ten, który sam tworzysz i uruchamiasz. To, co wszyscy mówią, jest tak dobre, jak „czek jest w poczcie”. Wiele razy udowodniłem, że wiele mitów i założeń jest błędnych, przeprowadzając własne testy porównawcze.
TravisO,
^ @TravisO - jest całkowicie poprawne. Kilka razy wolniej wykonywałem NOLOCK. Nie do końca wiem dlaczego, ale używam tego podczas rozwiązywania problemów i nie chcę negatywnie (nadmiernie) wpływać na produkcję
StingyJack
2
  • Odpowiedź brzmi Tak, jeśli zapytanie jest uruchamiane wiele razy jednocześnie, ponieważ każda transakcja nie będzie musiała czekać na zakończenie innych. Jeśli jednak zapytanie zostanie uruchomione samodzielnie, odpowiedź brzmi Nie.

  • Tak . Istnieje duże prawdopodobieństwo, że staranne użycie Z (NOLOCK) ogólnie przyspieszy twoją bazę danych. Oznacza to, że inne transakcje nie będą musiały czekać na zakończenie instrukcji SELECT, ale z drugiej strony inne transakcje zostaną spowolnione, ponieważ dzielą teraz swój czas przetwarzania z nową transakcją.

Uważaj, aby używać tylkoWITH (NOLOCK) w instrukcjach SELECT w tabelach, które mają indeks klastrowany.

Z (NOLOCK) jest często wykorzystywany jako magiczny sposób na przyspieszenie transakcji odczytu bazy danych.

Zestaw wyników może zawierać wiersze, które nie zostały jeszcze zatwierdzone, a które często są później wycofywane.

Jeśli Z (NOLOCK) zostanie zastosowane do tabeli, która ma indeks nieklastrowany, wówczas indeksy wierszy można zmienić za pomocą innych transakcji, ponieważ dane wiersza są przesyłane strumieniowo do tabeli wyników. Oznacza to, że w zestawie wyników może brakować wierszy lub wyświetlać ten sam wiersz wiele razy.

CZYTAJ ZOBOWIĄZANIE dodaje dodatkowy problem, w którym dane są uszkodzone w jednej kolumnie, w której wielu użytkowników zmienia tę samą komórkę jednocześnie.

WonderWorker
źródło