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

Zakleszczenie SQL z operacjami wyboru/aktualizacji na tabeli

Dwa zapytania powodujące zakleszczenie to SELECT poniżej (process id="process3980de4558" ):

select @existing = team_it_cube_attr_05 from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key

Oraz UPDATE zapytanie poniżej (process id="process386ed48188" ):

UPDATE D
SET D.team_rss_attr_01 = LEFT(S.mkt_prodchar_13,25)...

<resource-list> sekcja zwraca uwagę na SELECT zapytanie posiadało blokadę na wyłączność (X) na stronie i próbowało uzyskać blokadę współdzieloną intencją (IS) na innej stronie podczas odczytu danych. UPDATE zapytanie miało już blokadę IS i próbowało uzyskać blokadę X na stronie w celu wykonania aktualizacji.

Biorąc pod uwagę sprzężenie z tą tabelą:

...from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key...
...INNER JOIN tbl_Ref_Attr_Prod_Team D ON D.prod_key=P.prod_key...

SELECT zapytanie posiada już wyłączną blokadę. To prawdopodobnie oznacza, że ​​jest to część większej transakcji, która już wykonała UPDATE w poprzednim zapytaniu. Blokady z wcześniejszych zapytań zostaną zachowane w celu zachowania integralności danych podczas transakcji (w zależności od poziom izolacji transakcji ).

UPDATE zapytanie musi odczytać tabelę tbl_Ref_Attr_Prod_team . Uzyskuje współdzielone intencje na stronach i wierszach podczas odczytu danych. Gdy UPDATE zapytanie znajdzie pasujące wiersze, spróbuje przekonwertować blokady IS na blokady X. Zamki IS nie są kompatybilne z blokadami X. Ponieważ SELECT zapytanie ma już blokadę IS na jednej lub więcej z tych stron, zapytania zakleszczą się nawzajem.

Jedną z możliwych przyczyn może być brak indeksów w tbl_Ref_Attr_Prod_team.prod_key . Bez indeksu w tej kolumnie UPDATE zapytanie będzie skanować wszystkie wiersze w tabeli tbl_Ref_Attr_Prod_team .

Nawet jeśli indeks istnieje na prod_key , jeśli w tabeli jest niewielka liczba wierszy, SQL Server może zdecydować, że wydajność byłaby lepsza, gdyby zapytanie przeskanowało całą tabelę zamiast szukać indeksu. Zapisanie planu zapytania w momencie wystąpienia impasu zweryfikowałoby tę teorię.

Regularnie spotykamy się z zakleszczeniami małych tabel podczas uruchamiania nowych baz danych. Początkowo tabele są małe, a skanowanie tabel powoduje różnego rodzaju zakleszczenia. Później, gdy tabele są większe, obliczony koszt skanowania tabeli przekracza koszt wyszukiwania indeksu i zakleszczenia już nie występują. W środowiskach testowych, w których liczba wierszy jest zawsze mała, uciekliśmy się do użycia FORESEEK i WITH INDEX wskazówki, aby wymusić wyszukiwanie indeksu zamiast skanowania. Nie możemy się doczekać, aby móc wymusić plany zapytań za pomocą funkcji magazynu zapytań w SQL Server 2016.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zaktualizuj wartość kolumny null z wartości innej niż null w poprzednim wierszu

  2. Instrukcja SQL CASE:Co to jest i jakie są najlepsze sposoby jej wykorzystania?

  3. Zdefiniuj kroki dla kursora SQL Server — samouczek SQL Server / TSQL

  4. Zakleszczenie z zakresu blokad na indeksie klucza podstawowego

  5. Jak wstawić aktualną datę w kolumnie wiersza