我有一个主表
A
,约有 900 万行。另一个表 B
(相同的结构)包含表 A
中的约 28K 行。从表 B
中删除 A
的所有内容的最佳方法是什么?
所有列(~10)的组合都是唯一的。没有更多的形式是唯一的密钥。
如果您有足够的权限,您可以创建一个新表并将其重命名为 A。要创建新表,您可以使用以下脚本:
CREATE TABLE TEMP_A AS
SELECT *
FROM A
MINUS
SELECT *
FROM B
这应该表现得很好。
DELETE FROM TableA WHERE ID IN(SELECT ID FROM TableB)
应该可以。不过可能需要一段时间。
一种方法,只需列出所有列
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)
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
这可能会非常慢,因为您必须对每个列建立索引,这在这种大小的表没有主键的环境中极不可能,因此请在非高峰期间进行。是什么让你拥有一张有 900 万条记录且没有主键的表?
如果这是您必须定期执行的操作,那么第一个选择应该是尝试改进数据库设计(寻找主键,尝试使“连接”条件出现在尽可能少的列上) ).
如果这是不可能的,第二个不同的选择是找出每列的“选择性”(即每列有多少个“不同”值,“名称”比“地址国家/地区”更具选择性) “男/女”)。 我建议的一般声明类型如下:
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 中的确切列数将是一些试验和测量的结果。 (用delete语句的改进时间来抵消tableB建索引的时间。)
如果这只是一次性操作,我只会选择上面概述的慢速方法之一。当你可以在回家之前开始一个声明时,可能不值得花太多时间去考虑这个问题......
有可用的键值(或多个值)吗?
类似的东西
DELETE a
FROM tableA a
INNER JOIN tableB b
on b.id = a.id