检查大表中的完整重复行

时间:2013-06-14 13:01:01

标签: sql postgresql exists duplicates postgresql-8.1

我在这里可以找到所有相关背景的原始问题:
Adding a multi-column primary key to a table with 40 million records

我有一个包含4000万行且没有主键的表。在我添加主键之前,我想检查表是否有任何重复的条目。当我说重复条目时,我不仅仅意味着在特定列上重复。我的意思是在整行上重复。

我在上一个问题中被告知我可以执行EXISTS查询来确定重复项。我该怎么做?

我正在运行PostgreSQL 8.1.22。 (通过运行select version()获得此信息)。

2 个答案:

答案 0 :(得分:1)

要查找 任何 完整重复是否存在(所有列都相同),这可能是最快的方式:

SELECT EXISTS (
    SELECT 1
    FROM   tbl t
    NATURAL JOIN tbl t1 
    WHERE  t.ctid <> t1.ctid
    )

NATURAL JOIN是一个非常方便的简写,因为(引用the manual here):

  

NATURALUSING列表的简写,提及了所有列中的列   两个具有相同名称的表。

EXISTS可能是最快的,因为Postgres会在找到第一个副本后立即停止搜索。由于你很可能没有覆盖整行的索引而你的桌子很大,这将为你节省很多时间。

请注意, NULL 永远不会与另一个NULL相同。如果您有NULL个值并认为它们相同,则必须执行更多操作。

ctid is a system column可以(ab-)用作ad-hoc主键,但从长远来看不能替换实际的用户定义主键。


过时的版本8.1似乎没有为<>定义ctid运算符。尝试转换为text

SELECT EXISTS (
    SELECT 1
    FROM   tbl t
    NATURAL JOIN tbl t1 
    WHERE  t.ctid::text <> t1.ctid::text
    )

答案 1 :(得分:0)

不应该这样做吗?

SELECT ALL_COLUMNS[expect unique ID],
       count(0) as Dupl 
FROM   table 
WHERE  Dupl>1
GROUP BY ALL_COLUMNS[expect unique ID];

不确定它是否是最有效的方式,但是计数&gt; 1意味着你有两个相同的行。