对于那些寻求最快速方式的人,我最近发现了这些基准测试,显然使用“INSERT SELECT... EXCEPT SELECT...”在处理5000万条记录或更多时是最快的。
以下是文章中的一些示例代码(第3个代码块最快):
INSERT INTO #table1 (Id, guidd, TimeAdded, ExtraData)
SELECT Id, guidd, TimeAdded, ExtraData
FROM #table2
WHERE NOT EXISTS (Select Id, guidd From #table1 WHERE #table1.id = #table2.id)
-----------------------------------
MERGE #table1 as [Target]
USING (select Id, guidd, TimeAdded, ExtraData from #table2) as [Source]
(id, guidd, TimeAdded, ExtraData)
on [Target].id =[Source].id
WHEN NOT MATCHED THEN
INSERT (id, guidd, TimeAdded, ExtraData)
VALUES ([Source].id, [Source].guidd, [Source].TimeAdded, [Source].ExtraData);
------------------------------
INSERT INTO #table1 (id, guidd, TimeAdded, ExtraData)
SELECT id, guidd, TimeAdded, ExtraData from #table2
EXCEPT
SELECT id, guidd, TimeAdded, ExtraData from #table1
------------------------------
INSERT INTO #table1 (id, guidd, TimeAdded, ExtraData)
SELECT #table2.id, #table2.guidd, #table2.TimeAdded, #table2.ExtraData
FROM #table2
LEFT JOIN #table1 on #table1.id = #table2.id
WHERE #table1.id is null
insert
语句始终是单个事务。SQL Server不会先评估子查询,然后在某个稍后的时间点,而且没有保持锁定的情况下进行插入。 - Ed AvisUPDLOCK
和HOLDLOCK
查询提示,否则在检查完成后,对EmailsRecebidos
的锁定将立即释放,就在写入同一表之前的瞬间。在这一刹那间,另一个线程仍然可以读取表并假设记录不存在,并遇到竞争条件。通过使用显式事务和锁定提示,可以阻止在选择语句完成后释放表上的锁定。锁将保持到事务提交为止。 - GarethD