我有一个使用相当大的表(数百万行,大约30列)的Web应用程序。我们称之为TableA。在30列中,此表有一个名为“id”的主键,另一列名为“campaignID”。
作为应用程序的一部分,用户可以上传与新“广告系列”相关的新数据集。
这些数据集与TableA具有相同的结构,但通常只有大约10,000-20,000行。
新数据集中的每一行都会有一个唯一的“ID”,但它们都会共享相同的campaignID。换句话说,用户正在加载新“广告系列”的完整数据,因此所有10,000行都具有相同的“campaignID”。
通常,用户正在上传新广告系列的数据,因此TableA中没有具有相同campaignID的行。由于“id”对于每个广告系列都是唯一的,因此每个新数据行的ID在TableA中都是唯一的。
但是,在极少数情况下,用户尝试为已存在于数据库中的“广告系列”加载一组新行,则要求首先从TableA中删除该广告系列的所有旧行,然后插入来自新数据集的新行。
所以,我的存储过程很简单:
这很好用。
但新要求是在用户上传新数据以处理“重复”时为用户提供3个选项 - 用户正在为已在TableA中的广告系列上传数据的实例。
用户无法逐行选择此选项。她选择如何合并数据,并将此逻辑应用于整个数据集。
在我使用MySQL的类似应用程序中,我使用“LOAD DATA INFILE”函数,使用“REPLACE”或“IGNORE”选项。但我不知道如何使用SQL Server / T-SQL执行此操作。
任何解决方案都需要足够高效来处理TableA有数百万行的事实,而#TableB(新数据集)可能有10k-20k行。
我搜索了类似“Merge”命令(SQL Server 2008似乎支持的东西),但我只能访问SQL Server 2005.
在粗糙的伪代码中,我需要这样的东西:
如果用户选择选项1: [我都在这里 - 我有这个工作]
如果用户选择选项2(替换):
merge into TableA as Target
using #TableB as Source
on TableA.id=#TableB.id
when matched then
update row in TableA with row from #TableB
when not matched then
insert row from #TableB into TableA
如果用户选择选项3(保留):
merge into TableA as Target
using #TableB as Source
on TableA.id=#TableB.id
when matched then
do nothing
when not matched then
insert row from #TableB into TableA
答案 0 :(得分:2)
这个怎么样?
选项2:
begin tran;
delete from tablea where exists (select 1 from tableb where tablea.id=tableb.id);
insert into tablea select * from tableb;
commit tran;
选项3:
begin tran;
delete from tableb where exists (select 1 from tablea where tablea.id=tableb.id);
insert into tablea select * from tableb;
commit tran;
至于性能,只要tablea(大表)中的id字段被索引,你应该没问题。
答案 1 :(得分:0)
为什么你声称他想要合并时使用Upserts? SQL 2008中的MAREG更快,更高效。
我会让合并处理差异。