删除大型 postgresql 数据库表中的重复行

Posted

技术标签:

【中文标题】删除大型 postgresql 数据库表中的重复行【英文标题】:delete duplicate rows in large postgresql database table 【发布时间】:2013-07-25 07:52:09 【问题描述】:

我有一个 100 GB 大小的 postgresql 数据库。其中一张表有大约十亿个条目。为了快速输入数据,一些数据被重复并留待以后修剪。其中一列可用于将行标识为唯一的。

我找到了this *** question,它为 mysql 提出了一个解决方案:

ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime)

postgresql 有类似的吗?

我尝试使用 group by 和行号删除,在这两种情况下,我的计算机在几个小时后都会耗尽内存。

这是我尝试估计表中的行数时得到的结果:

SELECT reltuples FROM pg_class WHERE relname = 'orders';
  reltuples  
-------------
 4.38543e+08
(1 row)

【问题讨论】:

你能显示你的表 DDL 和你正在执行的删除语句吗?如果您将删除转换为选择计数(*),您的删除目标是多少行? @JustBob select count(1) 花了一个多小时才停止。 我的想法是批量删除。我很好奇您的删除是在 2 行还是 3 亿行之后进行。如果您有一个很好的索引列,它是一个序列,您可以在行集上滑动并从那里删除。您必须编写一个 python 脚本或其他东西来循环从表中删除,其中 id 介于 min 和 max 之间并提交。执行此操作,直到您到达表的末尾,其中 min 和 max 更改为高于上一个的范围,但仍然只在说 50,000 条记录之后。有意义吗? @JustBob 是的,如果归根结底,我将不得不使用光标以编程方式删除重复项。现在试图理解 bma 的建议。我认为您的想法和他的额外专栏可以一起使用以删除重复项。 @nurettin 我的建议 #1 假设您正在删除 100GB 表的很大一部分并且不希望与大量删除(或一系列删除)相关联的膨胀.如果您只有几百万行要删除,那么请分批执行,并在每次运行后运行 VACUUM。 【参考方案1】:

立即想到两个解决方案:

1)。使用 WHERE 子句创建一个新表作为 select * from source table 以确定唯一行。添加索引以匹配源表,然后在事务中重命名它们。这是否对您有用取决于几个因素,包括可用磁盘空间量、表是否在持续使用以及是否允许访问中断等。创建新表的好处是可以紧密打包数据和索引,并且由于省略了非唯一行,因此该表将小于原始表。

2)。在列上创建部分唯一索引并添加 WHERE 子句以过滤掉非唯一索引。 例如:

test=# create table t ( col1 int, col2 int, is_unique boolean);
CREATE TABLE

test=# insert into t values (1,2,true), (2,3,true),(2,3,false);
INSERT 0 3

test=# create unique index concurrently t_col1_col2_uidx on t (col1, col2) where is_unique is true;
CREATE INDEX

test=# \d t
        Table "public.t"
  Column   |  Type   | Modifiers 
-----------+---------+-----------
 col1      | integer | 
 col2      | integer | 
 is_unique | boolean | 
Indexes:
    "t_col1_col2_uidx" UNIQUE, btree (col1, col2) WHERE is_unique IS TRUE

【讨论】:

以上是关于删除大型 postgresql 数据库表中的重复行的主要内容,如果未能解决你的问题,请参考以下文章

如果插入语句给出重复键异常(在表中找到行 id=1)如何更新 JDBC(Postgresql)中的语句

PostgreSQL删除数据

R:从R中的大型数据集中根据列中的值删除行[重复]

一种在大型 PostgreSQL 表中处理/合并“后继记录”的方法?

从 Advantage Database Server 10.1 表中删除重复行

查询删除临时表中的重复行