Вставьте строки из таблицы A, которых нет в таблице B, с помощью объединенных ключей

У меня 2 стола. TableA заполняется импортом csv и обычно содержит от 10 до 15 тысяч строк. TableB имеет ту же структуру и теперь разросся примерно до 95 тыс. строк. Чтобы определить строки в таблице A, которых нет в таблице B, мне нужно сравнить конкатенацию 4 полей в таблице A с такой же конкатенацией в таблице B.

Приведенный ниже код работает, поскольку TableB растет, но это занимает так много времени, что его необходимо отменить, и он не завершается.

Я твердо верю, что использование связанных полей для сравнения приводит к тому, что время выполнения выходит за пределы удобства использования.

Есть ли лучший подход к проблеме?

DELETE FROM billing..whse_Temp
BULK INSERT billing..whse_Temp
FROM '/mnt/ABC/ABC.csv'
WITH
(
  FORMAT='csv',
  FIRSTROW=2,
  FIELDTERMINATOR=',',
  ROWTERMINATOR='\r\n'
)

INSERT INTO billing..whse
SELECT * FROM billing..whse_Temp S
WHERE CONCAT(S.RunTimeStamp, S.CS_Datacenter,S.Customer, S.ServerName) NOT IN
  (
    SELECT CONCAT(RunTimeStamp, CS_Datacenter, Customer, ServerName) 
    FROM billing..whse
  )

Зачем вам использовать конкатенацию для смоделированного ключа? Просто так много способов, что это может пойти не так. Допустим, у вас есть клиенты Mandi и Mandie и серверы wok и ewok. Возможно, если вы используете CONCAT_WS и разделитель, который не может появиться в данных, но тем не менее, да, поскольку таблица становится больше, это будет занимать все больше и больше времени. У billing..whse нет ключа? Не могли бы вы создать такой же ключ (или хотя бы эквивалентный неуникальный кластеризованный индекс) на billing..whse_Temp? Тогда вы могли бы объединиться по ключам вместо этого конкатенации вуду. Также рассмотрите NOT EXISTS вместо NOT IN.

Aaron Bertrand 02.05.2022 21:35

Этот запрос не подлежит анализу — полезные индексы не будут использоваться, если они существуют. Перестаньте использовать внешне умные уловки.

SMor 02.05.2022 21:40

В чем проблема с использованием обычной корреляции где не существует? Или Кроме?

Stu 02.05.2022 21:57
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
3
28
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Просто используйте NOT EXISTS:

INSERT INTO billing..whse
SELECT * FROM billing..whse_temp S
WHERE NOT EXISTS
(
  SELECT NULL
  FROM billing..whse w
  WHERE w.runtimestamp = s.runtimestamp
    AND w.cs_datacenter = s.cs_datacenter
    AND w.customer = s.customer
    AND w.servername = s.servername
);

Соответствующий индекс для этого:

CREATE INDEX idx ON billing..whse (runtimestamp, cs_datacenter, customer, servername);

Я уверен, что есть способы сделать это с помощью команды MERGE, но я никогда ими не пользовался. Я уверен, что есть способы с EXISTS в нескольких столбцах, но лично я считаю более ясным иметь полное условие соединения, а затем просто проверять, где соединение не удалось. (то есть: нет строки с правой стороны):

INSERT INTO billing..whse
SELECT S.* 
  FROM billing..whse_Temp S
       LEFT OUTER JOIN billing..whse W
         ON S.RunTimeStamp = W.RunTimeStamp
         AND S.CS_Datacenter = W.CS_Datacenter
         AND S.Customer = W.Customer
         AND S.ServerName = W.ServerName
WHERE W.RunTimeStamp IS NULL

Другие вопросы по теме