经典 SQL Server 操作
Posted
技术标签:
【中文标题】经典 SQL Server 操作【英文标题】:Classic SQL Server Operation 【发布时间】:2011-04-01 16:22:59 【问题描述】:我假设这是每个使用 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】:您是否尝试过左连接来检测不存在?
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
【讨论】:
在这种情况下,左连接可能会更糟,因为您不会期望空 id。 explainextended.com/2009/09/15/… @Jeff O. 我当然承认这可能不会更好,这就是我为什么写“你试过了吗……”的原因,但总有可能存在一些变量,Quassnoi 的实验没有t 考虑所以它值得一试。此外 id 不是唯一加入的字段,因此它有可能为空。【参考方案2】:你提供的那个解决方案还不错,你可以试试这个:
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);
你还能做什么?
如果您有可能将默认值为 0 的列添加到表 A,那么您可以使用存储过程进行迁移,您选择仅插入那些值为 0(不使用 null)的列,然后设置为他们 1. 使用此解决方案,您将不会扫描全表。
【讨论】:
以上是关于经典 SQL Server 操作的主要内容,如果未能解决你的问题,请参考以下文章