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

Pytanie o zakleszczenie SQL

SELECTy nie mogą zakleszczać się z innymi SELECT, ponieważ uzyskują tylko współdzielone blokady. Mówisz, że powinniśmy wziąć pod uwagę, że te SELECTy „wymagają wyłącznych blokad odczytu”, ale nie jest to dla nas możliwe, ponieważ 1) nie ma czegoś takiego jak exlusive read lock oraz 2) odczyty nie uzyskują wyłącznych blokad.

Ale stawiasz bardziej ogólne pytanie, czy proste stwierdzenia mogą się zakleszczyć. Odpowiedź brzmi:zdecydowane, głośne TAK . Blokady są nabywane podczas wykonywania, nie są analizowane z góry i sortowane, a następnie nabywane w określonej kolejności. Niemożliwe byłoby, aby silnik znał z góry potrzebne blokady, ponieważ zależą one od rzeczywistych danych na dysku i odczytał dane, których silnik potrzebuje do… zablokowania danych.

Zakleszczenia między prostymi instrukcjami (SELECT vs. UPDATE lub SELECT vs. DELETE) spowodowane różną kolejnością dostępu do indeksów są dość powszechne i bardzo łatwe do zbadania, zdiagnozowania i naprawienia. Pamiętaj jednak, że jest zawsze zaangażowana operacja zapisu, ponieważ odczyty nie mogą się wzajemnie blokować. W tej dyskusji dodanie wskazówki UPDLOCK lub XLOCK do SELECT należy uznać za zapis. Nie potrzebujesz nawet JOIN, dodatkowy indeks może wprowadzić problem z kolejnością dostępu prowadzący do zakleszczenia, patrz Zakleszczenie odczytu/zapisu .

I na koniec pisząc SELECT FROM A JOIN B lub pisząc SELECT FROM B JOIN A jest całkowicie nieistotne. Optymalizator zapytań może dowolnie zmieniać kolejność dostępu według własnego uznania, rzeczywisty tekst zapytania w żaden sposób nie narzuca kolejności wykonywania.

Zaktualizowano

Obawiam się, że nie ma przepisu na foremki do ciastek. Rozwiązanie będzie zależeć od przypadku. Ostatecznie w aplikacjach bazodanowych zakleszczenia są faktem. Rozumiem, że może to brzmieć absurdalnie, jak w przypadku „wylądowaliśmy na Księżycu, ale nie możemy napisać poprawnej aplikacji bazodanowej”, ale w grę wchodzą silne czynniki, które w dużej mierze gwarantują, że aplikacje w końcu napotkają impas. Szczęśliwe impasy to naj najłatwiej poradzić sobie z błędami, po prostu ponownie odczytać stan, zastosować logikę, przepisać nowy stan. Biorąc to pod uwagę, istnieją pewne dobre praktyki, które mogą radykalnie zmniejszyć częstotliwość impasów, aż do momentu, w którym prawie znikną:

  • Spróbuj mieć spójny wzorzec dostępu dla Zapisów . Miej jasno określone zasady, na przykład „transakcje powinny zawsze znajdować się w tabeli w następującej kolejności:Customers -> OrderHeaders -> OrderLines . Pamiętaj, że zlecenie musi być przestrzegane wewnątrz transakcji . Zasadniczo uszereguj wszystkie tabele w schemacie i określ, że wszystkie aktualizacje muszą odbywać się w kolejności rankingu. To ostatecznie sprowadza się do dyscypliny kodu indywidualnego współtwórcy piszącego kod, ponieważ musi zapewnić, że pisze i aktualizuje się w odpowiedniej kolejności wewnątrz transakcji.
  • Skróć czas trwania zapisów. Zwykła mądrość wygląda następująco:na początku transakcji wykonaj wszystkie odczyty (odczytaj istniejący stan), następnie przetwórz logikę i oblicz nowe wartości, a na końcu transakcji zapisz wszystkie aktualizacje. Unikaj wzorca typu „odczyt->zapis->logika->odczyt->zapis”, zamiast tego wykonuj „odczyt->odczyt->logic->zapis->zapis”. Oczywiście prawdziwe rzemiosło polega na tym, jak radzić sobie z rzeczywistymi, rzeczywistymi, indywidualnymi przypadkami, gdy najwyraźniej jeden musi muszę zrobić pisze w połowie transakcji. W tym miejscu należy zwrócić szczególną uwagę na specyficzny typ transakcji:te kierowane przez kolejkę, które z definicji rozpoczynają swoją działalność od dekolejkowania (=zapisu) z kolejki. Aplikacje te zawsze były niezwykle trudne do napisania i podatne na błędy (szczególnie impasy), na szczęście są na to sposoby, patrz Używanie tabel jako kolejek .
  • Zmniejsz liczbę odczytów. Skanowanie tabel to naj najczęstszą przyczyną zakleszczeń. Właściwe indeksowanie nie tylko wyeliminuje zakleszczenia, ale może również zwiększyć wydajność procesu.
  • Izolacja migawki . Jest to najbardziej zbliżona rzecz do darmowego lunchu, jeśli chodzi o uniknięcie impasu. Celowo umieszczam go na końcu, ponieważ może maskować inne problemy (takie jak nieprawidłowe indeksowanie) zamiast je naprawiać.

Próbuję rozwiązać ten problem za pomocą LockCustomerByXXX podejście Obawiam się, że nie działa. Pesymistyczne blokowanie nie skaluje się. Optymistyczna współbieżność aktualizacje są naj droga do zrobienia, jeśli chcesz mieć przyzwoitą wydajność.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak utworzyć plik wyjściowy csv z procedury składowanej w SQL Server

  2. Uwzględnij brakujące miesiące w zapytaniu Grupuj według

  3. Generuj **nagie** instrukcje CREATE TABLE i CREATE PROC w SQL Server

  4. Nieprawidłowa suma, gdy dołączam do drugiego stołu

  5. Tworzenie nowej bazy danych z kopii zapasowej innej bazy danych na tym samym serwerze?