Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Podstawy i użycie podpowiedzi NOLOCK w SQL Server

Główną ideą mechanizmu blokowania SQL Server jest kontrolowanie spójności transakcji. Zgodnie z tą zasadą, jeśli proces chce wykonać operacje wstawiania, usuwania lub aktualizacji, silnik SQL Server blokuje wiersz lub wiersze i nie zezwala na inny proces do czasu zakończenia transakcji. W pewnych okolicznościach ten mechanizm blokujący może prowadzić do problemów z wydajnością, takich jak wysokie współbieżne ciśnienia procesowe. Możesz więc doświadczyć impasu (zakleszczenie jest problemem współbieżności, w którym dwie transakcje chcą jednocześnie uzyskać dostęp do tych samych danych) w Twojej bazie danych. W tym artykule skupimy się na tym, jak uniknąć problemów z blokadą za pomocą podpowiedzi NOLOCK. Najpierw nauczmy się głównych podstaw i szczegółów metodologii nieczystości, ponieważ wskazówka NOLOCK może powodować nieczysty odczyt.

Brudna lektura: W tej metodologii odczytu proces odczytu odczytuje niezatwierdzone dane, a proces odczytu nie dba o otwarte transakcje, więc blokady nie prowadzą do żadnych problemów w procesie odczytu. W rezultacie ten rodzaj odczytu zmniejsza problemy z blokowaniem. Jednak metodologia „brudnego odczytu” ma swoje wady i zalety, ponieważ „brudne czytanie” może powodować problemy z niespójnością w zestawie wyników instrukcji SELECT. Jak już wspomniano, te zestawy wyników mogą zawierać dane o niezatwierdzonych transakcjach, dlatego musimy wziąć pod uwagę nieczysty odczyt przy podejmowaniu decyzji o dokonaniu tego rodzaju odczytu. Nie możemy być pewni dokładności wierszy, które robimy podczas brudnego odczytu, ponieważ wiersze te można cofnąć. Z drugiej strony, ten rodzaj odczytu pozwala nam uniknąć problemów z blokowaniem i zwiększyć wydajność SQL Server.

NOLOCK: Domyślny poziom izolacji SQL Server to Read Committed i na tym poziomie izolacji SQL Server nie pozwala na odczytanie zablokowanych obiektów, które są zablokowane przez niezatwierdzone transakcje. Ponadto te zablokowane obiekty można zmieniać zgodnie z eskalacją blokady.

Uwaga:w tym artykule dotyczącym głównej koncepcji blokowania programu SQL Server można znaleźć szczegółowe informacje na temat blokowania i eskalacji blokad.

Wyobraź sobie, że masz dwóch użytkowników bazy danych, którzy chcą wykonać aktualizację i wybrać operację na bazie danych. Pierwszy użytkownik zaczyna aktualizować określony wiersz w tabeli, a drugi użytkownik chce czytać ten sam wiersz. Ci dwaj użytkownicy wykonują następującą aktualizację i wybierają instrukcje, co pokazano na poniższym obrazku.

W tym przypadku użytkownik2 czeka co najmniej 10 sekund, a następnie transakcja zostanie wycofana przez użytkownika1, a następnie użytkownik2 może odczytać zielony wiersz, ponieważ zablokowany wiersz zostanie zwolniony przez użytkownika1. Jest to domyślne zachowanie poziomu izolacji SQL Server Read Committed.

Teraz zademonstrujemy ten przypadek w SQL Server. Przede wszystkim utworzymy tabelę FruitSales i jej wiersze.

CREATE TABLE FruitSales(Id INT IDENTITY (1,1) PRIMARY KEY, [Name] Varchar(20) ,SalesTotal Float)GOINSERT INTO FruitSales VALUES('Apple',10) ,('Orange',8), ( „Banan”,2)

W tym kroku otworzymy dwa okna zapytań SQL Server Management Studio i wykonamy zapytanie user1, a następnie zapytanie user2.

 ---USER1----BEGIN TRANS UPDATE FruitSales SET SalesTotal =20 WHERE Id=2 CZEKAJ NA OPÓŹNIENIE '00:00:10'ROLLBACK TRANSAKCJA ---USER2----USTAW STATYSTYKI CZAS ONSELECT * FROM FruitSales WHERE Id=2

Jak widać na powyższym obrazku, drugie zapytanie czeka na wycofanie transakcji użytkownika1.

Teraz omówimy podpowiedź NOLOCK i szczegóły użycia. Wskazówka NOLOCK jest najpopularniejszą wskazówką dotyczącą tabeli, która jest używana przez programistów i administratorów baz danych w celu wyeliminowania problemów z blokadą w bazach danych SQL Server. Za pomocą podpowiedzi do tabeli NOLOCK możemy odczytać zablokowane obiekty (wiersz, strona lub tabela), które są zablokowane przez otwarte transakcje. Wskazówka NOLOCK zastępuje domyślne zachowanie optymalizatora zapytań SQL Server, tak aby instrukcja select mogła odczytać zablokowane obiekty.

Teraz dodamy wskazówkę NOLOCK do instrukcji user2 select, a następnie rozpoczniemy aktualizację user1, a następnie wykonamy instrukcję user2 select.

---UŻYTKOWNIK1----POCZĄTEK AKTUALIZACJI TRANSFERU FruitSales SET SalesTotal =20 WHERE Id=2 CZEKAJ NA OPÓŹNIENIE '00:00:10'ROLLBACK TRANSAKCJA ---USER2----USTAW STATYSTYKI CZAS ONSELECT * FROM FruitSales WITH (NOLOCK) GDZIE Id=2

W tym kroku wyjaśnimy, jak wpłynąć na wskazówkę NOLOCK w instrukcji user2 select. Użytkownik1 wykonuje zaktualizowaną instrukcję w jawnej transakcji, a następnie użytkownik2 wykonuje instrukcję SELECT, a zestaw wyników bezzwłocznie zwraca zakończenie transakcji. To jest główna idea NOLOCK, czyta zablokowane obiekty.

Teraz skupimy się na zestawie wyników instrukcji select. Instrukcja select użytkownika2 pobrała wartość SalesTotal 20, ale rzeczywista wartość SalesTotal nadal wynosi 8. Należy pamiętać, że jeśli korzystasz z podpowiedzi do tabeli NOLOCK w instrukcji select, możesz napotkać tego typu niedokładne wyniki danych.

Wskazówka: Słowo kluczowe „Z” jest przestarzałą funkcją, dlatego firma Microsoft zaleca, aby nie używać go w opracowywaniu nowych baz danych i usunąć słowo kluczowe „Z” w bieżących opracowaniach. Możesz znaleźć użycie podpowiedzi NOLOCK bez słowa kluczowego „Z”.

---USER1----BEGIN TRANS UPDATE FruitSales SET SalesTotal =20 WHERE Id=2 WAITFOR DELAY '00:00:10'ROLLBACK TRANSACTIONSELECT * FROM FruitSales WHERE Id=2 --USER2---SELECT * FROM FruitSales (NOLOCK) GDZIE Id=2

Ponadto wskazówka tabeli READUNCOMMITTED jest odpowiednikiem wskazówki NOLOCK i możemy użyć wskazówki READUNCOMMITTED zamiast wskazówki NOLOCK.

WYBIERZ * Z FruitSales (ODCZYTAJ NIEZAKOŃCZONO) WHERE Id=2

Mimo to istnieje szczególny przypadek dotyczący podpowiedzi NOLOCK, który nie może przekroczyć bariery blokującej. Jeśli jakiś proces zmienia tabelę, wskazówka NOLOCK nie może pokonać tego typu blokady i nie może kontynuować operacji odczytu. Powodem tego problemu jest to, że wskazówka NOLOCK przejmuje blokadę Sch-S (stabilność schematu), a instrukcja ALTER TABLE przejmuje blokadę SCH-M (modyfikacja schematu), więc występuje konflikt.

Najpierw poznamy tabelę Object_Id FruitSales za pomocą następującego zapytania.

wybierz OBJECT_ID('FruitSales')

Uruchom następującą kwerendę user1, a następnie uruchom kwerendę user2. W rezultacie zapytanie user2 opóźni zakończenie procesu zmiany tabeli user1.

--USER1---POCZĄTEK TABELI TRANALTERÓW FruitSalesADD ColorofFruit varchar(200) CZEKAJ NA OPÓŹNIENIE '00:00:35GOCOMMIT TRAN --USER2---SELECT * FROM FruitSales (NOLOCK) WHERE Id=2

Otwórz nowe okno zapytania i wykonaj następujące zapytanie. To zapytanie pomoże znaleźć typ blokady zapytań użytkownika1 i użytkownika2.

SELECT Typ_zasobu, Identyfikator_bazy_zasobu, Opis_zasobu, Identyfikator_związanego_zasobu, Zasób_blokada_partycja, Tryb_żądania, Typ_żądania, Stan_żądania, Identyfikator_sesji_żądania, Identyfikator_żądania_żądania, Typ_właściciela_żądania, Identyfikator_właściciela_żądania, Lock_owner_addressFROM sys. 

Teraz sprawdzimy macierz kompatybilności zamków dla interakcji SCH-M i SCH-S. Macierz opisuje, że interakcja SCH-M i SCH-S powoduje konflikt.

Wniosek

W tym artykule wspomnieliśmy o brudnym procesie czytania i wskazówce NOLOCK. Użycie podpowiedzi NOLOCK jest skuteczną metodą odczytywania zablokowanej strony, ale ma też pewne zalety i wady. Z tego powodu przed użyciem należy wziąć pod uwagę wskazówkę NOLOCK.

Referencje

Przewodnik dotyczący blokowania transakcji SQL Server i wersjonowania wierszy

Wskazówki (język Transact-SQL) — tabela

USTAW POZIOM IZOLACJI TRANSAKCJI (Transact-SQL)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Co SqlDbType mapuje na varBinary(max)?

  2. SQL Server konwertujący varbinary na string

  3. Jak zrobić LEWE SEMI JOIN w SQL Server

  4. Wstawianie danych SQL Server do Salesforce.com

  5. Funkcje skalarne ODBC dla daty i godziny w SQL Server (przykłady T-SQL)