【问题标题】:Remove Duplicate rows from a large table - PostgreSQL从大表中删除重复行 - PostgreSQL
【发布时间】:2019-10-18 19:45:45
【问题描述】:

我想从一个大约有 100 万行并且每小时都在增加的大表中删除重复项。它没有唯一的 id,大约有 575 列,但填充得很少。

该表“类似于”一个日志表,其中每小时添加新条目,没有唯一的时间戳。

重复项大约是 1-3%,但我还是想删除它;)有什么想法吗?

我尝试了 ctid 列(如here),但速度很慢。

【问题讨论】:

    标签: postgresql duplicates


    【解决方案1】:

    与 PostgreSQL 一起工作的基本思想是在整个列集的哈希上创建一个索引。

    例子:

    CREATE INDEX index_name ON tablename (md5((tablename.*)::text));
    

    这将起作用,除非有些列不能很好地满足不变性的要求(主要是 timestamp with time zone,因为它们的 cast-to-text 值取决于会话)。

    创建此索引后,可以通过自连接哈希快速找到重复项,查询如下所示:

    SELECT t1.ctid, t2.ctid
    FROM tablename t1 JOIN tablename t2
     ON (md5((t1.*)::text) = md5((t2.*)::text))
    WHERE t1.ctid > t2.ctid;
    

    您还可以使用此索引来避免将来重复行,而不是定期对它们进行重复数据删除,方法是将其设为 UNIQUE(重复行将在 INSERT 或 UPDATE 时被拒绝)。

    【讨论】:

    • 对我不起作用,因为我有 TZ 的时间戳,但我喜欢这种方法。
    • 我正在尝试做类似的事情,但带有时间戳。但是,我知道数据库是 UTC 并且(显然)时间戳也是如此;我正在寻找不变性的解决方法。我想从数百万行中删除数千个重复行,以便重新创建主键...
    • @Jeff:如果您有候选主键,则不需要上述方法。在其上创建一个索引,然后使用可能会使用该索引的自连接消除重复项,然后删除该索引,然后设置唯一约束。
    • 感谢领导!我会尝试一些事情,否则我会在这里创建一个新问题并让你知道。
    • @OmriShneor:这个答案似乎已经过时,如果您只需要对某些列进行重复数据删除,那么这无论如何都不是同一个问题。请提交一个新问题。
    猜你喜欢
    • 2013-07-25
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    相关资源
    最近更新 更多