如何从另一个表中“减去”一个表?

时间:2009-02-04 18:21:01

标签: sql-server

我有一个主表A,行数约为900万。另一个表B(相同的结构)具有表A中的~28K行。从表B中删除A的所有内容的最佳方法是什么?

所有列(~10)的组合都是唯一的。没有更多的形式是一个独特的钥匙。

6 个答案:

答案 0 :(得分:6)

如果您有足够的权限,您可以创建一个新表并将其重命名为A.要创建新表,您可以使用以下脚本:

CREATE TABLE TEMP_A AS
SELECT *
FROM   A
MINUS
SELECT *
FROM   B

这应该表现得非常好。

答案 1 :(得分:3)

DELETE FROM TableA WHERE ID IN(SELECT ID FROM TableB)

应该有效。可能需要一段时间。

答案 2 :(得分:2)

单向,只列出所有列

delete table a
where exists (select 1 from table b where b.Col1= a.Col1 
AND b.Col2= a.Col2 
AND b.Col3= a.Col3
AND b.Col4= a.Col4)

答案 3 :(得分:1)

Delete t2 
from t1 
inner join t2 
  on t1.col1 = t2.col1
  and t1.col2 = t2.col2
  and t1.col3 = t2.col3
  and t1.col4 = t2.col4
  and t1.col5 = t2.col5
  and t1.col6 = t2.col6
  and t1.col7 = t2.col7
  and t1.col8 = t2.col8
  and t1.col9 = t2.col9
  and t1.col10 = t2.col0

这可能非常慢,因为您必须将每个col编入索引,而在此大小的表没有主键的情况下环境中极不可能,因此在非高峰时执行此操作。是什么让你拥有一张包含900万条记录且没有主键的表?

答案 4 :(得分:1)

如果这是您必须定期进行的事情,首先应该尝试改进数据库设计(寻找主键,尝试将“连接”条件设置为几列尽可能)。

如果无法做到这一点,那么明显的第二个选择是找出每个列的“选择性”(即每列有多少“不同”值,'name'比'address country'更具选择性'比'男/女')。 我建议的一般声明类型如下:

Delete from tableA
where exists (select * from tableB
 where tableA.colx1 = tableB.colx1
 and tableA.colx2 = tableB.colx2
 etc. and tableA.colx10 = tableB.colx10).

我们的想法是按照选择性的顺序列出列,并在tableB上的colx1,colx2等上构建索引。表B中的确切列数将是一些试验和测量的结果。 (使用删除语句的改进时间来抵消在tableB上构建索引的时间。)

如果这只是一次性操作,我只选择上面提到的一种慢速方法。当你回家之前就可以开始做一个声明时,可能不值得花太多考虑这个......

答案 5 :(得分:0)

是否有可以使用的键值(或值)?

类似

DELETE a
FROM tableA a
INNER JOIN tableB b
on b.id = a.id