Как да преработим този проблем с безизходица?

Сблъсках се с проблем с безизходица synchronizing таблица няколко пъти за кратък период от време. Под синхронизиране имам предвид извършване на следното:

  1. Вмъкнете данни за синхронизиране във временна таблица
  2. Актуализирайте съществуващите записи в целевата таблица
  3. Вмъкнете нови записи в целевата таблица
  4. Изтриване на записи, които не са в таблицата за синхронизиране при определени обстоятелства
  5. Таблица за спад на температурата

За операторите INSERT и DELETE използвам LEFT JOIN, подобно на:

INSERT INTO destination_table (fk1, fk2, val1)
FROM #tmp
LEFT JOIN destination_table dt ON dt.fk1 = #tmp.fk1
   AND dt.fk2 = #temp.fk2
WHERE dt.pk IS NULL;

Графиката на блокиране отчита, че първичният ключ на table_table е под изключително заключване. Предполагам, че горната заявка причинява заключване на таблица или страница вместо заключване на ред. Как да потвърдя това?

Бих могъл да пренапиша горната заявка с команда IN, EXIST или EXCEPT. Има ли допълнителни начини за преработване на кода? Рефакторингът с помощта на някоя от тези команди ще избегне ли проблема с блокиране? Кое би било най-доброто? Предполагам EXCEPT.


person anon    schedule 31.01.2015    source източник
comment
Всичко това в транзакция ли се прави? Какво ниво на изолация на транзакция използвате? Има ли друга дейност, използваща целевата таблица?   -  person HABO    schedule 01.02.2015


Отговори (1)


Е, при нормални обстоятелства бих могъл да изпълня сценария доста добре. По-долу е тестовият скрипт, който създадох. Пробваш ли нещо друго?

drop table #destination_table
drop table #tmp

Declare @x int=0

create table #tmp(fk1 int, fk2 int, val int)

set @x=2

while (@x<1000)
begin
    insert into #tmp
    select @x,@x,100
    set @x=@x+3
end

create table #destination_table(fk1 int, fk2 int, val int)
while (@x<1000)
begin
    insert into #destination_table
    select @x,@x,100
    set @x=@x+1
end



INSERT INTO #destination_table (fk1, fk2, val)
select t.*
FROM #tmp t
LEFT JOIN #destination_table dt ON dt.fk1 = t.fk1
     AND dt.fk2 = t.fk2
WHERE dt.fk1 IS NULL
person UVData    schedule 01.02.2015
comment
Тъй като вашият тест използва само локални временни таблици, достъпни от една връзка, е малко по-малко вероятно да създаде задънена улица. - person HABO; 01.02.2015