我从第三方获得数据并导入到 SQL 服务器。该表有 255,072,636 条记录,其中 61,714,772 条记录是唯一的。该表既没有特定的顺序,也没有任何索引。该表有 4 列:Field1(float), Field2(varchar(255), Field3(varchar(255), Field4(varchar(255)
。我想根据已运行以下查询的 Field1
删除重复记录:
WITH CTE(Field1, Field2, Field3, Field4, DuplicateCount)
AS (SELECT *,
ROW_NUMBER() OVER(PARTITION BY Field1 ORDER BY Field1) AS DuplicateCount
FROM MyTable)
DELETE FROM CTE
WHERE DuplicateCount > 1;
但是花了 13 个小时,然后我取消了它,上面提到的数字是在那之后。有没有更好的方法来删除重复项?
答案 0 :(得分:2)
您可以将唯一行插入到临时表中,而不是删除,然后您可以重命名该表或在截断该表后将所需的行复制到原始表中。
在表格中插入唯一的行。
WITH CTE(Field1, Field2, Field3, Field4, DuplicateCount)
AS (SELECT *,
ROW_NUMBER() OVER(PARTITION BY Field1 ORDER BY Field1) AS DuplicateCount
FROM MyTable)
select * into TempTable FROM CTE
WHERE DuplicateCount = 1;
然后,您可以像下面这样重命名该表:
drop table MyTable;
sp_rename 'temptable','MyTable';
或者将唯一的行复制回原始表:
Truncate table MyTable;
insert into MyTable select *from TempTable ;
drop table temptable;
答案 1 :(得分:1)
我会这样做:
在filed1 上建立索引(这需要几个小时)
create ix_table on MyTable(files1)
然后要么删除重复项,要么为唯一值创建一个新表,如果您只是插入到新表中,速度可能会快一点
SELECT Field1, Field2, Field3, Field4
from
( select * ,
ROW_NUMBER() OVER(PARTITION BY Field1 ORDER BY Field1) AS dups
FROM MyTable
) tt
where dups = 1
但是如果你从原始表中删除,但是它会更慢,你已经在该表的 field1 上有一个索引,如果你以后需要使用该索引进行任何查询。所以从长远来看,保留原始表可能更有效
答案 2 :(得分:0)
只需重新创建表:
select distinct *
into new_t
from t;
我建议在执行此操作之前在 (field1, field2, field3, field4)
上添加索引。
或者对于一列唯一性:
select t.*
from (select t.*,
row_number() over (partition by field1 order by (select null)) as seqnum
from t
) t
where seqnum = 1;
为此,您需要 (field1)
上的索引。
如果您确实需要重新使用原始表的名称,请将其截断并从 new_t
重新插入或重命名该表。
答案 3 :(得分:0)
感谢“Kazi Mohammad Ali Nur”和“eshirvana”。我已经结合了那里的解决方案。起初,我在 Field1
上创建了索引。
CREATE CLUSTERED INDEX Index_Name
ON MyTable(Field1);
然后我执行以下查询将唯一记录插入新表并删除原始表。
WITH CTE(Field1, Field2, Field3, Field4, DuplicateCount)
AS (SELECT *,
ROW_NUMBER() OVER(PARTITION BY Field1 ORDER BY Field1) AS DuplicateCount
FROM MyTable)
select * into TempTable FROM CTE
WHERE DuplicateCount = 1;
它奏效了。
谢谢大家。