可以在此处找到包含所有相关上下文的原始问题:
向具有 4000 万条记录的表添加多列主键
我有一个包含 4000 万行且没有主键的表。在添加主键之前,我想检查表是否有任何重复条目。当我说重复条目时,我不仅仅指在特定列上重复。我的意思是整行重复。
我在上一个问题中被告知我可以进行EXISTS
查询以确定重复项。我该怎么做?
我正在运行 PostgreSQL 8.1.22。(通过运行获得此信息select version()
)。
可以在此处找到包含所有相关上下文的原始问题:
向具有 4000 万条记录的表添加多列主键
我有一个包含 4000 万行且没有主键的表。在添加主键之前,我想检查表是否有任何重复条目。当我说重复条目时,我不仅仅指在特定列上重复。我的意思是整行重复。
我在上一个问题中被告知我可以进行EXISTS
查询以确定重复项。我该怎么做?
我正在运行 PostgreSQL 8.1.22。(通过运行获得此信息select version()
)。
要查找是否存在任何完整的重复项(在所有列上都相同),这可能是最快的方法:
SELECT EXISTS (
SELECT 1
FROM tbl t
NATURAL JOIN tbl t1
WHERE t.ctid <> t1.ctid
)
NATURAL JOIN
是该案例的一种非常方便的速记,因为(在此处引用手册):
NATURAL
USING
是提及两个表中具有相同名称的所有列的列表的简写。
EXISTS
可能是最快的,因为 Postgres 会在找到第一个重复项后立即停止搜索。由于您很可能没有覆盖整行的索引并且您的表很大,因此这将为您节省大量时间。
请注意,NULL
它永远不会被视为与另一个相同NULL
。如果您有NULL
价值观并认为它们相同,那么您必须做更多。
ctid
是一个系统列,可以(ab-)用作临时主键,但从长远来看不能替换实际的用户定义的主键。
过时的 8.1 版似乎没有<>
为ctid
. 尝试投射到text
:
SELECT EXISTS (
SELECT 1
FROM tbl t
NATURAL JOIN tbl t1
WHERE t.ctid::text <> t1.ctid::text
)
不应该这样的事情吗?
SELECT ALL_COLUMNS[expect unique ID],
count(0) as Dupl
FROM table
WHERE Dupl>1
GROUP BY ALL_COLUMNS[expect unique ID];
不确定它是否是最有效的方法,但 count>1 表示您有两个相同的行。