大表上的独特分组

时间:2015-07-15 21:11:11

标签: sql sql-server

我有一个相当大的表(约2000万),主键列和另一列有大文本字符串(~250 char)。主键列都是唯一的,但文本字符串具有重复。我想删除所有冗余的文本字符串并“分离”表格或创建一个新的表格以达到相同的效果。 我想只留下具有不同文本字符串的行。我不关心每个URL的几个主键中的哪一个被丢弃。即使仅在字符串列上运行select distinct也会导致内存溢出。还有哪些其他选择?

4 个答案:

答案 0 :(得分:1)

您的内存溢出可能是由于将如此大的结果返回到SSMS。如果你Select min(ID), TextColumn Into TableXYZ Group By TextColumn,你应该解决这个问题。一旦' Distinctified'结果在一个单独的表中,然后您可以继续删除/存档原始表中的记录。

答案 1 :(得分:1)

在某个级别,这与How can I remove duplicate rows?中提出的问题相同。

您可以使用the ROW_NUMBER approach,但这需要对2000万行进行排序。或the GROUP BY approach,如果它使用散列聚合,可能需要更少的内存。

此处可能考虑的另一种另类方法,因为您预计将保留少于50%的表格,将创建一个新表格,如下所示

CREATE TABLE Deduped
(
Id INT,
CharColumn VARCHAR(255) PRIMARY KEY CLUSTERED WITH (IGNORE_DUP_KEY = ON)
)

并将所有行插入其中

DECLARE @I INT = 2000000000;
INSERT INTO Deduped
SELECT TOP(@I) Id, CharColumn
FROM   OriginalTable
OPTION (OPTIMIZE FOR (@I = 0))

这可能会完全避免使用任何内存操作符,因为使用正在创建的B树会丢弃重复项。

答案 2 :(得分:1)

select column1_primary, column2_text, count(*) from table group by column2_text, column1_primary   having count(*) > 1

在此之后,您将获得包含重复文本的记录,然后您可以运行:

Delete from table where column2_primary in(select column1_primary, count(*) from table group by column2_text, column1_primary   having count(*) > 1)

这将从表中删除所有重复文本,左后表将包含唯一字符串,或者您可以使用insert select在新表中插入行。

我在700万条记录表上对此进行了测试,选择行需要大约1分钟。

答案 3 :(得分:0)

比查找和删除更好的是可以插入新表。您可以直接将您的不同结果选择到新表中。如果像COUNT()OVER或GROUP BY这样的东西不起作用,你仍然可以使用CURSOR并逐个执行此操作。使用一个唯一的密钥并开始尝试...捕捉。