Wstawiałem dwa zestawy danych, używając minimalnego rejestrowania, do pustej tabeli sterty, używając dwóch zadań wykonywania SQL równolegle i za pomocą SQL o następującej formie.
INSERT INTO Table (TABLOCK) SELECT FROM ...
Po tym, jak zadanie trochę się zawiesiło, jedno z zadań SQL stało się ofiarą impasu. Poniżej znajduje się wyjście XML wykresu zakleszczenia.
Czy ktoś może wyjaśnić, co działo się pod maską?
<resource-list>
<objectlock lockPartition="0" objid="1586156746" subresource="FULL" dbid="7" objectname="dbo.TargetTable" id="lock7374a00" mode="IX" associatedObjectId="1586156746">
<owner-list>
<owner id="process9609dc8" mode="Sch-S"/>
<owner id="process9609dc8" mode="IX"/>
</owner-list>
<waiter-list>
<waiter id="process5e13048" mode="X" requestType="convert"/>
</waiter-list>
</objectlock>
<objectlock lockPartition="0" objid="1586156746" subresource="FULL" dbid="7" objectname="dbo.TargetTable" id="lock7374a00" mode="IX" associatedObjectId="1586156746">
<owner-list>
<owner id="process5e13048" mode="Sch-S"/>
<owner id="process5e13048" mode="IX"/>
</owner-list>
<waiter-list>
<waiter id="process9609dc8" mode="X" requestType="convert"/>
</waiter-list>
</objectlock>
</resource-list>
Sprawy stają się o wiele trudniejsze, ponieważ stwierdziłem, że w większości przypadków dwa zadania wykonywania SQL mogą działać równolegle z powodzeniem. Spróbuj poniżej:
Create table dbo.TablockInsert (c1 int, c2 int, c3 int)
--then issue the script in two Execute Sql Task in parallel you won't fail:
insert into dbo.TablockInsert(TABLOCK) SELECT 1, 1, 1
Ponieważ jedyną różnicą jest instrukcja SELECT ... FROM ..., wygląda na to, że instrukcja SELECT ... FROM ... może mieć tutaj wpływ na tryb blokady?
Odpowiedzi:
Danych Ładowanie Wydajność przewodnik został napisany dla SQL Server 2008, ale o ile mogę powiedzieć Microsoft nie dokonał żadnych ulepszeń w tej dziedzinie na stosach. Oto oferta Twojego scenariusza ładowania:
Ważne jest to, że nie dostajesz blokady BU
INSERT ... SELECT
. Zawsze otrzymasz ekskluzywną blokadę na stole, więc tylko jednaINSERT
może działać jednocześnie.W komentarzach powiedziałeś, że wstawisz 100 tys. Wierszy lub mniej i że inne procesy nie będą działały na tabelach podczas wstawiania. Podczas wysyłania dwóch zapytań INSERT do bazy danych oczekiwałbym jednej z trzech rzeczy:
We wszystkich przypadkach zyskujesz lub nie cierpisz, dodając
TABLOCKX
wskazówkę do zapytania, więc to moja rekomendacja obejścia impasu. Jeśli chcesz wiedzieć, dlaczego czasami występuje impas, musisz poszukać innej odpowiedzi.W innym scenariuszu, w którym naprawdę potrzebujesz równoległego wstawiania, dwa sposoby obejścia problemu BU to podzielenie sterty i umieszczenie każdej sesji w osobnej partycji lub załadowanie danych przez BCP, BULK INSERT lub Integration Services .
źródło
Wstawiasz w
dbo.TargetTable
dwóch sesjach, używając obuTABLOCK
podpowiedzi. Obaprocess9609dc8
iprocess5e13048
przetrzymywanie procesówSch-S
orazIX
blokady, które są ze sobą kompatybilne, dzięki czemu oba procesy mogą odbywać się w tym samym czasie. Ale oboje chcą przekonwertowaćIX
blokadę naExclusive X
typ.X
zamki nie są ze sobą kompatybilne. Dlatego serwer SQL wybrał jedną z sesji jako ofiarę impasu zamiast nieskończenie długo na siebie czekać.Podstawowe informacje o zakleszczeniu.
Zablokuj wykres zgodności (aparat bazy danych).
Wykrywanie i kończenie zakleszczeń.
źródło