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

Dlaczego ta kwerenda programu SQL Server jest blokowana?

  • Proces 9196a8 ma stronę 151867 slot 174 w trybie X i wymaga strony 140302 slot 31 w trybie S
  • Proces 88b5b8 ma stronę 140302 slot 31 w trybie X i wymaga strony 151867 slot 174 w trybie S
  • dwa usunięcia działają pod isolationlevel="odczyt powtarzalny (3)"

Tak więc zakleszczenie występuje na stercie podstawowej tabeli (blokady RID zamiast blokad klawiszowych oznaczają stertę, a nie Btree). Wysoki poziom izolacji (prawdopodobnie spowodowany przez kod DTC, sądząc po dokładnej nazwie) sprawia, że ​​ustawienie RCSI jest nieistotne.

Jakiego typu są kolumny PARTYEXTERNALREF i PARTYTYPE? Przekazywane parametry to NVARCHAR (tj. Unicode), a jeśli kolumny to VARCHAR (tj. Ascii), to zgodnie z regułami pierwszeństwo typu danych indeks NC nie byłby używany. Ze względu na stosowane skanowanie tabeli oraz wysoki poziom izolacji w użyciu, zakleszczenie jest prawie nieuniknione.

Rozwiązaniem byłoby użycie parametrów typu VARCHAR dla @P0 i @P1, aby wykorzystać indeks NC w celu uniknięcia skanowania tabeli.

Jeśli parametry są już typu VARCHAR i możesz potwierdzić na podstawie planu wykonania, że ​​używane jest wyszukiwanie na NC, moje pierwsze pytanie będzie brzmiało inne czy transakcja wykonuje inne niż wyciągi z usuwania?

BTW, podajesz tylko nazwę indeksu NC, ale zakładam, że jest na (PARTYEXTERNALREF, ISCOUNTERPARTY, PARTYID) .

Aktualizuj

Ponieważ Twój komentarz mówi, że kolumny NVARCHAR to hipoteza skanowania tabel jest prawdopodobnie błędna. Istnieją jeszcze trzy możliwości spowodowania impasu, które wymagają zbadania:

  • wszelkie inne wyciągi uruchamiane przez transakcję przed DELETE (jest to najbardziej prawdopodobne)
  • dowolne nakładanie się wierszy wybranych przez dwie instrukcje DELETE biorące udział w zakleszczeniu
  • kolizja skrótu

Tylko w przypadku dwóch pierwszych hipotez możesz teraz cokolwiek zrobić (zbadaj, czy są poprawne). W przypadku ostatniego mogę powiedzieć, jak to zweryfikować, ale nie jest to trywialne. Jest to mało prawdopodobne i trochę trudne do udowodnienia, ale jest to możliwe. Ponieważ znasz przypadek zakleszczenia (załączony plik XML), użyj go jako bazy dochodzenia:

  • przywróć kopię bazy danych z określonego momentu z zatrzymaniem na 2011-09-02T19:00:29.690
  • uruchom DBCC TRACEON(3604,-1)
  • przy użyciu STRONA DBCC (, 1, 151867, 3) sprawdź wartości w gnieździe 174
  • używając DBCC PAGE(, 1, 140302, 3)` sprawdź wartości w slocie 31
  • uruchom SELECT %%lockres%% FROM PARTIES WHERE PARTYEXTERNALREF =... AND ISCOUNTERPARTY='N' i PARTYID=... i przekaż wartości przeczytane powyżej
  • porównuje uzyskane wartości hash blokady, jeśli są zgodne, oznacza to kolizję hash i to spowodowało zakleszczenie.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. .NET SqlDependency z wieloma powiadomieniami a sondowaniem o wysokiej szybkości?

  2. Nie mogę wykonać ORDERBY na moich danych EF4

  3. UNION vs DISTINCT w wydajności

  4. Problem serializacji C# i SQL Server 2008 CLR

  5. Korzystanie z programu LAG programu SQL Server 2012