使用连接键从 TableA 插入不在 TableB 中的行

Insert rows from TableA that are not in TableB using concatenated keys

我有2张桌子。 TableA 由 csv 导入填充,通常包含 10k 到 15k 行。 TableB 具有相同的结构,现在已增长到大约 95k 行。为了确定 TableA 中不在 TableB 中的行,我需要比较 TableA 中 4 个字段的串联与 TableB 中的相同串联。

下面的代码一直在工作,因为 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
  )

只需使用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