Mat*_*att 5 postgresql duplication
我有一个包含 OS MasterMap 数据的非常大的表(约 1.14 亿行)。这是新表中新加载的数据。尝试设置主键时,出现此错误:
ERROR: could not create unique index "tbl_os_mmap_topoarea_pkey"
DETAIL: Key (toid)=(1000000004081308) is duplicated.
Run Code Online (Sandbox Code Playgroud)
不知何故,我最终得到了一个完全重复的行。这两行中的每个字段都相同。我想删除一行,但保留另一行。由于无法区分两者,如何做到这一点?
我想尽快和尽可能简单地做到这一点。创建临时表等并不是一个真正的选择,因为在这种大小的数据集上需要太长时间。我猜创建一个新的唯一 ID 列会更快,但也可能需要一些时间。
经过一番研究,我了解到 postgres 中的所有记录都有一个隐藏的唯一 ID,即 ctid。我可以用它来删除重复的行之一吗?
ype*_*eᵀᴹ 10
我认为这会起作用:
with d as
( select ctid, row_number() over (partition by t.*) as rn
from tablename as t
)
delete from tablename as t
using d
where d.rn > 1
and d.ctid = t.ctid ;
Run Code Online (Sandbox Code Playgroud)
还有另一种变体。不确定哪个更有效:
delete from tablename as t
where exists
( select *
from tablename as d
where d.ctid > t.ctid
and d.* is not distinct from t.*
) ;
Run Code Online (Sandbox Code Playgroud)
但请注意文档所说的内容ctid:
ctid行版本在其表中的物理位置。请注意,虽然
ctid可用于非常快速地定位行版本,但如果行ctid被更新或移动,则行将发生更改VACUUM FULL。因此ctid作为长期行标识符是无用的。应该使用OID,甚至更好的是用户定义的序列号来标识逻辑行。
因此,如果该表已创建WITH OIDS,请改用它。