使用连接键从 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
我有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