Zajmuję się tworzeniem witryn internetowych i aplikacji, które nie są krytyczne -> np. oprogramowanie bankowe, lot kosmiczny, aplikacja do monitorowania intensywnej terapii, itp. Masz pomysł.
Tak więc, przy tym ogromnym zastrzeżeniu, czy używanie wskazówki NOLOCK w jakimś oświadczeniu Sql jest złe? Kilka lat temu inny administrator Sql zasugerował, że powinienem używać NOLOCK, jeśli jestem zadowolony z „brudnego odczytu”, który da mi nieco większą wydajność poza moim systemem, ponieważ każdy odczyt nie blokuje tabela / wiersz / cokolwiek.
Powiedziano mi również, że to świetne rozwiązanie, jeśli mam martwe zamki. Więc zacząłem podążać za tą myślą przez kilka lat, aż guru Sql pomógł mi z jakimś przypadkowym kodem i zauważył wszystkie NOLOCKS w moim kodzie sql. Zostałem grzecznie zbesztany, a on próbował mi to wyjaśnić (dlaczego to nie jest dobre) i trochę się zgubiłem. Czułem, że esencją jego wyjaśnienia było „to bandażowe rozwiązanie poważniejszego problemu… zwłaszcza jeśli doświadczasz impasu. W związku z tym napraw źródło problemu ”.
Ostatnio trochę googlowałem na ten temat i trafiłem na ten post .
Więc, czy jakiś sql db guru sensei może mnie oświecić?
źródło
Odpowiedzi:
Ze wskazówką NOLOCK poziom izolacji transakcji dla
SELECT
instrukcji wynosiREAD UNCOMMITTED
. Oznacza to, że zapytanie może zobaczyć brudne i niespójne dane.Z reguły nie jest to dobry pomysł. Nawet jeśli to brudne zachowanie odczytu jest w porządku dla Twojej krytycznej aplikacji sieciowej, skanowanie NOLOCK może spowodować błąd 601, który zakończy zapytanie z powodu przenoszenia danych w wyniku braku ochrony blokującej.
Proponuję przeczytać książkę When Snapshot Isolation Helps and When It Boli - w większości przypadków MSDN zaleca użycie READ COMMITTED SNAPSHOT zamiast SNAPSHOT.
źródło
Przed rozpoczęciem pracy na przepełnienie stosu, byłem przeciwko
NOLOCK
na zasadzie, że potencjalnie można wykonaćSELECT
zNOLOCK
i wrócić wyniki z danych, które mogą być nieaktualne lub niezgodne. Należy przemyśleć, ile rekordów można wstawiać / aktualizować w tym samym czasie, gdy inny proces może wybierać dane z tej samej tabeli. Jeśli zdarza się to często, istnieje duże prawdopodobieństwo zakleszczenia, chyba że używasz trybu bazy danych, takiego jakREAD COMMITED SNAPSHOT
.Od tego czasu zmieniłem swoje
NOLOCK
podejście do korzystania z programu po obejrzeniu, jak może poprawićSELECT
wydajność, a także wyeliminować zakleszczenia na masowo ładowanym serwerze SQL. Czasami możesz nie przejmować się tym, że Twoje dane nie są dokładnie w 100% zatwierdzone i potrzebujesz szybko z powrotem uzyskać wyniki, nawet jeśli mogą być nieaktualne.Zadaj sobie pytanie, myśląc o użyciu
NOLOCK
:Jeśli odpowiedź brzmi nie, użyj,
NOLOCK
aby poprawić wydajność.Właśnie przeprowadziłem szybkie wyszukiwanie
NOLOCK
słowa kluczowego w bazie kodu dla przepełnienia stosu i znalazłem 138 wystąpień, więc używamy go w wielu miejscach.źródło
NOLOCK
. Oznacza to, że muszę zlekceważyć twoją odpowiedź. Przepraszam.SELECT
, odczytując tylko z indeksu pokrywającego, może spowodować zakleszczenie. SPID 1) zaczyna sięSELECT
od indeksu pokrywającego. SPID 2) UruchomUPDATE
tabelę. Aktualizacja przechodzi następnie do aktualizacji indeksu pokrycia.UPDATE
osiąga zakres indeksu zablokowany przezSELECT
i zostaje zablokowany. SPID 1) nadal przeszukuje indeks pokrywający, znajduje zakres zablokowany przezUPDATE
i zostaje zablokowany. DEADLOCK . Nic nie może rozwiązać tego impasu (z wyjątkiem przechwytywania błędu SQL Server 1205 i automatycznego ponawiania lub używaniaNOLOCK
)Jeśli nie przejmujesz się brudnymi odczytami (np. W sytuacji przeważnie READ), to
NOLOCK
jest w porządku.ALE należy pamiętać, że większość problemów z blokowaniem wynika z braku „poprawnych” indeksów dla obciążenia zapytaniami (zakładając, że sprzęt jest odpowiedni do zadania).
A wyjaśnienie guru było poprawne. Zwykle jest to bandażowe rozwiązanie poważniejszego problemu.
Edycja : zdecydowanie nie sugeruję, aby używać NOLOCK. Chyba powinienem był to jasno wyrazić. (Używałbym go tylko w ekstremalnych okolicznościach, w których przeanalizowałem, że jest OK). Jako przykład, jakiś czas temu pracowałem nad TSQL, który został spryskany NOLOCKem, aby spróbować złagodzić problemy z blokowaniem. Usunąłem je wszystkie, zaimplementowałem prawidłowe indeksy i WSZYSTKIE zakleszczenia zniknęły.
źródło
Wątpię, czy był to „guru”, który miał jakiekolwiek doświadczenie w dużym ruchu ...
Witryny internetowe są zwykle „brudne” do czasu, gdy osoba przegląda całkowicie załadowaną stronę. Rozważ formularz, który ładuje się z bazy danych, a następnie zapisuje edytowane dane? To idiotyczne, jak ludzie mówią, że brudne książki są takie nie, nie.
To powiedziawszy, jeśli masz wiele warstw tworzonych na wybranych elementach, możesz tworzyć niebezpieczną nadmiarowość. Jeśli masz do czynienia ze scenariuszami dotyczącymi pieniędzy lub statusu, potrzebujesz nie tylko odczytu / zapisu danych transakcyjnych, ale także odpowiedniego rozwiązania współbieżnego (coś, czym większość „guru” nie zawraca sobie głowy).
Z drugiej strony, jeśli masz zaawansowane wyszukiwanie produktów dla witryny internetowej (tj. Coś, co prawdopodobnie nie będzie buforowane i będzie trochę intensywne) i kiedykolwiek zbudowałeś witrynę z więcej niż kilkoma równoczesnymi użytkownikami (zjawisko to, ilu „eksperci” tego nie zrobili), niedorzeczne jest butelkowanie wszystkich innych procesów, które za tym stoją.
Dowiedz się, co to znaczy i używaj go w odpowiednich przypadkach. W dzisiejszych czasach Twoja baza danych prawie zawsze będzie Twoją główną szyjką, a rozsądne korzystanie z NOLOCK może zaoszczędzić tysiące na infrastrukturze.
EDYCJA: Pomaga nie tylko w zakleszczeniach, ale także na tym, jak bardzo wszyscy inni będą czekać, aż skończysz, lub odwrotnie.
Używasz NOLOCK Hint w EF4?
źródło
Żadna z odpowiedzi nie jest błędna, choć może trochę zagmatwana.
źródło
Jako profesjonalny programista powiedziałbym, że to zależy. Ale zdecydowanie postępuję zgodnie z radami GATS i OMG Kucy. Wiedz, co robisz, wiedz, kiedy to pomaga, a kiedy boli i
przeczytaj wskazówki i inne kiepskie pomysły
co może sprawić, że głębiej zrozumiesz działanie serwera sql. Generalnie kieruję się zasadą, że podpowiedzi SQL są ZŁE, ale niestety używam ich od czasu do czasu, gdy mam dość zmuszania serwera SQL do robienia pewnych rzeczy ... Ale to są rzadkie przypadki.
Łukasz
źródło
Kiedy obsługa aplikacji chciała odpowiedzieć na zapytania ad-hock z serwera produkcyjnego przy użyciu SSMS (które nie były obsługiwane przez raportowanie), poprosiłem, aby użyli nolock. W ten sposób nie ma to wpływu na „główną” działalność.
źródło
Zgadzam się z niektórymi uwagami na temat podpowiedzi NOLOCK, a zwłaszcza z tymi, które mówią „używaj jej, kiedy jest to właściwe”. Jeśli aplikacja jest źle napisana i używa współbieżności w niewłaściwy sposób - może to spowodować eskalację blokady. Stoły wysoce transakcyjne również są cały czas blokowane ze względu na ich charakter. Posiadanie dobrego pokrycia indeksu nie pomoże w pobieraniu danych, ale ustawienie POZIOMU IZOLACJI na ODCZYTAJ NIEZGODNE - tak. Uważam również, że używanie podpowiedzi NOLOCK jest bezpieczne w wielu przypadkach, gdy charakter zmian jest przewidywalny. Na przykład - w produkcji, gdy zadania z podróżnikami przechodzą przez różne procesy z dużą ilością wstawek pomiarów, możesz bezpiecznie wykonać zapytanie o ukończone zadanie za pomocą wskazówki NOLOCK i w ten sposób uniknąć kolizji z innymi sesjami, które stawiają PROMOTOWANE lub WYŁĄCZNE blokady na stole /strona. Dane, do których uzyskujesz dostęp w tym przypadku, są statyczne, ale mogą znajdować się w bardzo transakcyjnej tabeli z setkami milionów rekordów i tysiącami aktualizacji / wstawień na minutę. Twoje zdrowie
źródło
Uważam, że używanie nolocka praktycznie nigdy nie jest poprawne.
Jeśli czytasz pojedynczy wiersz, prawidłowy indeks oznacza, że nie będziesz potrzebować NOLOCK, ponieważ działania w poszczególnych wierszach są wykonywane szybko.
Jeśli czytasz wiele wierszy dla czegoś innego niż tymczasowe wyświetlanie i zależy Ci na możliwości powtórzenia wyniku lub obrony za pomocą wygenerowanej liczby, to NOLOCK nie jest odpowiedni.
NOLOCK jest zastępczym znacznikiem dla „Nie obchodzi mnie, czy ta odpowiedź zawiera zduplikowane wiersze, wiersze, które zostały usunięte lub wiersze, które nigdy nie zostały wstawione na początku z powodu wycofania”
Błędy, które są możliwe w NOLOCK:
Każda czynność, która może spowodować podział strony podczas działania funkcji noLock select, może spowodować takie zdarzenia. Prawie każda czynność (nawet usunięcie) może spowodować podział strony.
Dlatego: jeśli „wiesz”, że wiersz nie zostanie zmieniony podczas działania, nie używaj nolock, ponieważ indeks umożliwi wydajne pobieranie.
Jeśli podejrzewasz, że wiersz może się zmienić, gdy zapytanie jest uruchomione, i zależy Ci na dokładności, nie używaj nolock.
Jeśli rozważasz NOLOCK z powodu zakleszczeń, sprawdź strukturę planu kwerend pod kątem nieoczekiwanych skanów tabel, prześledź zakleszczenia i zobacz, dlaczego się pojawiają. NOLOCK wokół zapisów może oznaczać, że zapytania, które wcześniej były zakleszczone, mogą potencjalnie zarówno napisać błędną odpowiedź.
źródło
Lepszymi rozwiązaniami, jeśli to możliwe, są:
Poziom izolacji transakcji SNAPSHOT został utworzony, ponieważ firma MS traciła sprzedaż na rzecz Oracle. Oracle używa dzienników cofania / ponawiania, aby uniknąć tego problemu. Postgres używa MVCC. W przyszłości firma MS Heckaton będzie używać MVCC, ale to jeszcze lata od przygotowania do produkcji.
źródło
NOLOCK jest często wykorzystywany jako magiczny sposób na przyspieszenie odczytu bazy danych, ale staram się go unikać, gdy tylko jest to możliwe.
Zestaw wyników może zawierać wiersze, które nie zostały jeszcze zatwierdzone, które często są później wycofywane.
Zestaw błędów lub wyników może być pusty, brakować wierszy lub wyświetlać ten sam wiersz wiele razy.
Dzieje się tak, ponieważ inne transakcje przenoszą dane w tym samym czasie, gdy je czytasz.
PRZECZYTAJ ZATWIERDZONO dodaje dodatkowy problem polegający na uszkodzeniu danych w jednej kolumnie, gdy wielu użytkowników jednocześnie zmienia tę samą komórkę.
źródło
W prawdziwym życiu, gdy napotykasz systemy już napisane i dodawanie indeksów do tabel, a następnie drastycznie spowalnia ładowanie danych tabeli danych 14gig, czasami jesteś zmuszony do korzystania z NOLOCK w raportach i przetwarzania na koniec miesiąca, aby zagregowane funkcje (suma , count itp.) nie blokują wierszy, stron, tabel i nie wpływają negatywnie na ogólną wydajność. Łatwo powiedzieć, że w nowym systemie nigdy nie używaj funkcji WITH NOLOCK i nie używaj indeksów - ale dodanie indeksów poważnie obniża ładowanie danych, a kiedy zostaniesz poinformowany, zmień bazę kodu, aby usunąć indeksy, a następnie załaduj zbiorczo, a następnie ponownie utwórz indeksy - co wszystko dobrze, jeśli tworzysz nowy system. Ale nie wtedy, gdy masz już system.
źródło