Najlepsza sytuacja do zastosowania ODCZYTAJ NIEZAKOŃCZONY poziom izolacji

10

Jak wszyscy wiemy, READ UNCOMMITTED to najniższy poziom izolacji, w którym mogą gromadzić się takie rzeczy, jak brudne odczyty i odczyty fantomowe. Kiedy najlepiej wykorzystać ten poziom izolacji i z jakich powodów można go użyć?

Właściwie czytałem wcześniej odpowiedzi, ale nie mogłem tego całkowicie zrozumieć, ponieważ nie było wystarczającej liczby przykładów.

Peter Mortensen
źródło

Odpowiedzi:

20

Używam READ_UNCOMMITTED(lub NOLOCK) podczas odpytywania produkcyjnych baz danych z SSMS, ale nie rutynowo z kodu aplikacji. Ta praktyka (wraz ze wskazówką dotyczącą zapytań MAXDOP 1) pomaga zapewnić, że zwykłe zapytania do analizy danych i rozwiązywania problemów nie wpływają na obciążenie produkcyjne, przy założeniu, że wyniki mogą być niepoprawne.

Niestety widzę READ_UNCOMMITTED/ NOLOCKstosuję szeroko w kodzie produkcyjnym, aby uniknąć blokowania kosztem integralności danych. Właściwym rozwiązaniem jest poziom izolacji wersji wiersza ( SNAPSHOTlub READ_COMMITTEDz READ_COMMITTED_SNAPSHOTopcją bazy danych ON) i / lub uwaga na strojenie zapytań i indeksów.

Niedawno dokonałem przeglądu kodu procesu, w którym jedyną zmianą było usunięcie, NOLOCKponieważ czasami zwracało nieprawidłowe wyniki. Usunięcie NOLOCKbyło dobrą rzeczą, ale wiedząc, że pominięte lub zduplikowane wiersze zwykle zdarzają się podczas skanowania dużych tabel w kolejności alokacji , zasugerowałem również refaktoryzację, aby zastosować UNION ALLtechnikę promującą efektywne wykorzystanie indeksu. Zapytanie jest teraz uruchamiane w ciągu kilku milisekund z poprawnymi wynikami, najlepszymi ze wszystkich światów.

Dan Guzman
źródło
7

Myślę, że w pewnych okolicznościach jest w porządku , o ile akceptujesz konsekwencje i nie masz innych opcji.

W przypadku innych opcji zachęcałbym ludzi do korzystania z Read Committed Snapshot Isolation (RCSI) dla nowych aplikacji lub SNAPSHOT ISOLATION (SI) dla starszych aplikacji, gdzie nie można łatwo przetestować całej bazy kodu pod kątem warunków wyścigu z RCSI.

Mogą to jednak nie być dobre dopasowanie. Być może będziesz musiał poświęcić trochę czasu na kochanie i dbanie o tempdb oraz upewnienie się, że nikt nie pozostawia otwartej transakcji, która powoduje, że magazyn wersji (i tempdb) rośnie i zapełnia dysk.

Jeśli nie masz DBA lub osoby, której zadaniem jest monitorowanie i zarządzanie SQL Server, te opcje mogą być niebezpieczne. Mówiąc bardziej ogólnie, nie wszyscy mają pełną kontrolę nad kodem przechodzącym na serwer, na którym mogą zmienić parametry połączenia lub kod, aby poprosić SI o zapytania dotyczące problemów.

Poza tym większość ludzi nie ma problemów z blokowaniem całej aplikacji . Mają problemy z raportowaniem danych OLTP. Jeśli możesz zaakceptować kompromisy NOLOCK / RU w zamian za te raporty, które nie są blokowane przez pisarzy, idź do niego.

Upewnij się, że rozumiesz, co to znaczy. Nie oznacza to, że twoje zapytanie nie przyjmuje żadnych blokad, oznacza, że ​​nie respektuje blokad usuniętych przez inne zapytania.

I oczywiście, jeśli twoim problemem jest program zapisujący / blokujący zapisujący, jedyną opcją, która pomoże, jest SI, ale zajmie to niewiarygodną ilość pracy programisty, aby poprawnie wdrożyć to z obsługą błędów itp.

Erik Darling
źródło
5
A jeśli problemem jest po prostu raportowanie danych OLTP, odciąż to do jakiegoś wtórnego typu tylko do odczytu (AG, wysyłanie dziennika, replikacja lub roll-your-own).
Aaron Bertrand
3
@AaronBertrand A potem mieliby drugi serwer do monitorowania;)
Erik Darling
5

IMHO jedynym prawidłowym przypadkiem użycia READ UNCOMMITTED w nowoczesnym systemie jest debugowanie jednej sesji z drugiej w fazie rozwoju, dzięki czemu można zobaczyć, co robi, gdy np. Nadal działa zapisany procesor. Zwykle nigdy nie byłby używany w systemie produkcyjnym. Może wystąpić niewielki wzrost wydajności, ale w dłuższej perspektywie nigdy nie będzie tego wart.

Gajusz
źródło
3

Cały czas używamy go w służbie zdrowia.

Zadziwiająco rzadko zdarza się, że poszczególne wiersze danych zmieniają się w połowie zapytania, a współczynnik odczytu / zapisu wynosi 10 000/1 - i większość z nich to wstawki, a nie aktualizacje. Na przykład, gdy interfejs laboratorium zapisuje wyniki badania pacjenta w bazie danych, te wartości nigdy się nie zmienią.

Gdy dane się zmieniają, zmienia się jeden wiersz na raz. Nikt nie aktualizuje całych kolumn (z wyjątkiem DBA, gdy naprawdę psują się naprawdę źle).

Z drugiej strony uruchamiamy szereg zapytań, aby wyszukać takie rzeczy, jak pacjenci wracający do ER w ciągu 72 godzin lub krócej, co absolutnie uderza w stół.

Przez 10 lat SQL opieki zdrowotnej nigdy nie widziałem Rollback Transaction. Chcę wchodzić i wychodzić bez zakłócania wrażeń użytkownika końcowego. Jeśli istnieje wysokie ryzyko spowolnienia bazy danych OLTP i niskie ryzyko uzyskania złych danych, NOLOCK.

Czy powinniśmy tego użyć? Może, może nie. Ogólnie rzecz biorąc, nie powiedziałbym, że wiele baz danych aplikacji, nad którymi pracowałem, jest dobrze zaprojektowanych. Zazwyczaj są pełne klinów anty-wzorów.

James
źródło
4
tylko FYI, można czytać częściowo zapisane wiersze za pomocą nolock.
Max Vernon
1
Oo! Naprawdę muszę przekonać mojego szefa, żeby kupił mi inny serwer, abym mógł zalogować się do wysyłania tych rzeczy ....
James
3
Być może zainteresuje Cię ten fajny post na blogu od Paula White'a o CZYTAJ NIEPOKOMITOWANY, zwłaszcza sekcja „Czytanie uszkodzonych danych”: Odczyt niezaangażowanego poziomu izolacji
Josh Darnell
1

READ_UNCOMMITTED/NOLOCKjest dobrym rozwiązaniem, gdy dokładność danych nie jest tak naprawdę głównym celem. Czasami, gdy wymagana jest tylko przybliżona liczba agregatów. Na przykład: Istnieją procedury składowane, które są używane w tabelach INSERT lub UPDATE. Czasami liczba rekordów do aktualizacji lub wstawienia jest ogromna (Tysiące rekordów). Podczas tych uruchomionych procedur przechowywanych możemy NOLOCKokresowo uruchamiać proste zapytanie selekcyjne z tabelą docelową, aby sprawdzić, czy przebiega ono płynnie (w przypadku zapytania aktualizacyjnego, jeśli masz kolumnę zmiany statusu dla rekordów aktualizowanych, możemy użyć tej kolumny do uruchomienia group byzapytania z NOLOCKaby sprawdzić, czy liczba zmian stanu ciągle się zmienia).

GirKarr
źródło
0

Pamiętaj, że READ UNCOMMITTED wprowadza dodatkowe problemy ze spójnością, a nie tylko brudne odczyty. W zależności od metody dostępu możesz pominąć wiersze lub nawet przeczytać ten sam wiersz więcej niż raz. Jeśli jesteś zainteresowany szczegółami, przeczytaj artykuł Itzika Ben-Gana

SQLRaptor
źródło
3
Brakujące wiersze i czytanie wierszy więcej niż jeden raz jest możliwe również na domyślnym poziomie zatwierdzonego odczytu. Jeśli kolumna klucza indeksu jest aktualizowana podczas skanowania i się przesuwa.
Martin Smith,
Dyskusja boczna na temat tej odpowiedzi została przeniesiona na czat .
Paul White 9