经典 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_AtableSRC_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 操作的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server常见操作

Sql Server经典SQL语句大全

[C#对sql操作]C#对sql server 2008数据库操作

SQL Server经典sql语句大全(转)

sql SQL Server索引操作。

经典SQL Server语句大全(超详细)