2011-04-01 36 views
3

我认为这是每个使用SQL Server的人最常见的情况。经典SQL Server操作

场景:

我有这些表tabSRC_A(id,date,data1)tabSRC_B(id,Date,data2)tabDEST

现在我的任务是从tableSRC_A获取数据,适用tableSRC_B对他们的一些筛选和清理,并将其插入到tabDEST

我做这个使用下面的代码

insert into tabDest(id, Date, Data1, Data2) 
    Select id, date, Data1, Data2 
    from tabSRC_A A 
    inner join tabSRC_B B on A.id = B.id and A.date = B.date 
    where not exists 
      (select * from tabDest Dest 
       where Dest.id = B.id and Dest.date = B.date) 

和我更新,如果已经存在

这是该操作的最佳解决方案?

表的规模1000万行,每行

我也想用上面的方法

创建与代理键的视图和执行检查根据id,而不是检查每一行像这样的东西

insert into tabDest(id, Date, Data1, Data2) 
    Select id, date, Data1, Data2 
    from view_Created_From_TabA_TabB_adding_a_SurrogateKey_Kid SV 
    where SV.Kid > select (max(id) from tabDest) 

我假设这会快得多。

请引导我与您有任何建议。

(我使用的是SQL Server 2000中,我知道它很老)

回答

1

您已经尝试了LEFT JOIN检测不存在?

insert into tabDest(id, Date, Data1, Data2) 
    Select id, date, Data1, Data2 
    from tabSRC_A A 
    inner join tabSRC_B B on A.id = B.id and A.date = B.date 
    LEFT JOIN tabDest Dest 
    ON Dest.id = B.id and Dest.date = B.date 
WHERE 
    Dest.id is null 
+0

在这种情况下,左连接可能会更糟,因为您不会期望空id。 HTTP:// explainextended。com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/ – JeffO 2011-04-01 20:40:57

+0

@Jeff O.我当然承认它可能不会更好,我为什么我写下了“你有没有试过...”,但总有一种可能性,即Quassnoi的实验没有考虑过这个值得一试的变量。此外,id不是唯一加入的字段,因此可能为null。 – 2011-04-01 20:59:22

0

该解决方案必须提供不坏,你可以试试这个:

insert into tabDest(id, Date, Data1, Data2) 
    Select A.id, A.date, Data1, Data2 
    from tabSRC_A A 
    inner join tabSRC_B B on A.id = B.id and A.date = B.date 
    left join tabDest D.id = B.id and d.date = b.date 
    where d is null; 

不同的是,子查询将执行器一次为每个行,在这种情况下,左连接将会完成一次,但看着桌子的大小,这也会很慢,差别可能会很小。

视图接缝的创建是多余的,因为通常它们不比查询快,带id的想法很好,但在你的情况下,日期在识别中也有一些作用。这导致我得出结论,你不能使用这种比较,你可以有不同的时间两个相同的ID。

如果当ID是唯一的,你可以使用此语句

insert into tabDest(id, Date, Data1, Data2) 
    Select A.id, A.date, Data1, Data2 
    from tabSRC_A A 
    inner join tabSRC_B B on A.id = B.id and A.date = B.date 
    where A.id > (SELECT max(d.id) FROM Dest d); 

,你还有什么可以做?

如果您有可能向表A添加默认值为0的列,那么您可以使用存储过程进行迁移,您可以选择仅插入具有值0的列(不使用空值),然后设置给他们1.使用这种解决方案,你不会扫描全表。