Двете заявки, причиняващи блокиране, са SELECT
по-долу (process id="process3980de4558"
):
select @existing = team_it_cube_attr_05 from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key
И UPDATE
заявка по-долу (process id="process386ed48188"
):
UPDATE D
SET D.team_rss_attr_01 = LEFT(S.mkt_prodchar_13,25)...
<resource-list>
раздел отбелязва SELECT
query притежава изключително (X) заключване на страница и се опитва да получи заключване със споделено намерение (IS) на друга страница, докато чете данни. UPDATE
заявката вече притежава IS заключване и се опитваше да получи X заключване на страница, за да извърши актуализацията.
Предвид съединението срещу тази таблица:
...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
заявката вече притежава изключително заключване. Това вероятно означава, че е част от по-голяма транзакция, която вече е извършила UPDATE
в предишно запитване. Заключванията от предишни заявки ще се поддържат, за да се запази целостта на данните по време на транзакцията (в зависимост от ниво на изолация на транзакция
).
UPDATE
заявката трябва да прочете таблицата tbl_Ref_Attr_Prod_team
. Той придобива споделени заключвания на страници и редове, докато чете данни. Когато UPDATE
query намери съответстващите редове, тя ще се опита да преобразува IS заключванията в X заключвания. IS заключванията не са съвместими с X заключванията. Тъй като SELECT
заявката вече има IS заключване на една или повече от тези страници, заявките блокират една с друга.
Една възможна причина би била липсващите индекси на tbl_Ref_Attr_Prod_team.prod_key
. Без индекс в тази колона, UPDATE
заявката ще сканира всички редове в таблицата tbl_Ref_Attr_Prod_team
.
Дори ако съществува индекс на prod_key
, ако има малък брой редове в таблицата, SQL Server може да реши, че производителността би била по-добра, ако заявката сканира цялата таблица, вместо да търси индекса. Записването на плана на заявката при възникване на безизходица би потвърдило тази теория.
Редовно срещаме задънени блокировки на малки таблици, когато създаваме нови бази данни. Първоначално таблиците са малки и сканирането на таблици причинява всякакви задънени блокировки. По-късно, когато таблиците станат по-големи, изчислената цена за сканиране на таблицата надвишава цената за търсене на индекса и блокиранията вече не възникват. В тестови среди, където броят на редовете е винаги малък, прибягнахме до използването на FORESEEK
и WITH INDEX
съвети за принудително търсене по индекс вместо сканиране. Очакваме с нетърпение да можем да налагаме планове за заявки чрез функцията за съхранение на заявки на SQL Server 2016.