Классическая работа с SQL Server - PullRequest
3 голосов
/ 01 апреля 2011

Я предполагаю, что это самый распространенный сценарий для всех, кто работает с SQL Server.

Сценарий:

У меня есть эти таблицы tabSRC_A(id,date,data1), tabSRC_B(id,Date,data2) и tabDEST

Теперь моя задача - получить данные из tableSRC_A, tableSRC_B, применить к ним некоторую фильтрацию и очистку и вставить их в tabDEST.

Я делаю это, используя следующий код

insert into tabDest(id, Date, Data1, Data2)
   Select id, date, Data1, Data2 
   from tabSRC_A A 
   inner join tabSRC_B B on A.id = B.id and A.date = B.date
   where not exists 
             (select * from tabDest Dest 
              where Dest.id = B.id and Dest.date = B.date)

и я обновляюсь, если уже существует

Это лучшее решение для этой операции?

Размер таблиц составляет 10 миллионов строк

Я также думал о создании представления с суррогатным ключом и выполнении проверки на основе идентификатора вместо проверки каждой строки с использованием вышеуказанного метода

как то так

 insert into tabDest(id, Date, Data1, Data2)
    Select id, date, Data1, Data2 
    from view_Created_From_TabA_TabB_adding_a_SurrogateKey_Kid SV
    where SV.Kid > select (max(id) from tabDest) 

Я предполагаю, что это будет намного быстрее.

Пожалуйста, направьте меня с любыми предложениями.

(я использую SQL Server 2000, я знаю, что он очень старый)

Ответы [ 2 ]

1 голос
/ 01 апреля 2011

Вы пытались использовать левое соединение, чтобы обнаружить, что оно не существует?

insert into tabDest(id, Date, Data1, Data2)
   Select id, date, Data1, Data2 
   from tabSRC_A A 
   inner join tabSRC_B B on A.id = B.id and A.date = B.date
   LEFT JOIN tabDest Dest 
   ON Dest.id = B.id and Dest.date = B.date
WHERE
   Dest.id is null
0 голосов
/ 01 апреля 2011

Это решение, которое вы предлагаете, неплохо, вы можете попробовать это:

insert into tabDest(id, Date, Data1, Data2)
   Select A.id, A.date, Data1, Data2 
   from tabSRC_A A 
   inner join tabSRC_B B on A.id = B.id and A.date = B.date
   left join tabDest D.id = B.id and d.date = b.date
   where d is null;

Разница заключается в том, что подзапрос будет выполняться один раз для каждой строки, и в этом случае левое соединение будет выполнено один раз, но, глядя на размер таблицы, это также будет медленным, и разница может быть незначительной.

Создание швов представления должно быть избыточным, потому что, как правило, они не быстрее, чем запрос, идея с id хороша, но в вашем случае дата также играет определенную роль в идентификации. Это приводит меня к выводу, что вы не можете использовать это сравнение, и у вас может быть два одинаковых идентификатора с разным временем.

В случае, если идентификатор уникален, вы можете использовать это утверждение

insert into tabDest(id, Date, Data1, Data2)
   Select A.id, A.date, Data1, Data2 
   from tabSRC_A A 
   inner join tabSRC_B B on A.id = B.id and A.date = B.date
   where A.id > (SELECT max(d.id) FROM Dest d); 

Что еще можно сделать?

Если у вас есть возможность добавить один раз столбец в таблицу A со значением по умолчанию 0, тогда вы можете использовать хранимую процедуру для миграции, вы выбираете вставить только те столбцы, которые имеют значение 0 (не использовать ноль), а затем вы установите их 1. Используя это решение, вы не будете сканировать полную таблицу.

...