【问题标题】:Find difference between two big tables in PostgreSQL在 PostgreSQL 中查找两个大表之间的差异
【发布时间】:2013-02-26 03:31:03
【问题描述】:

我在 Postgres 中有两个相似的表,只有一个 32 字节的拉丁字段(简单的 md5 哈希)。 两个表都有约 30,000,000 行。表格差别不大(10-1000行不一样)

Postgres 是否可以找到这些表之间的差异,结果应该是我上面描述的 10-1000 行。

这不是一个真正的任务,我只是想知道 PostgreSQL 是如何处理类似 JOIN 的逻辑的。

【问题讨论】:

标签: sql postgresql left-join exists full-outer-join


【解决方案1】:

EXISTS 似乎是最好的选择。

tbl1 是本例中包含多余行的表:

SELECT *
FROM   tbl1
WHERE  NOT EXISTS (SELECT FROM tbl2 WHERE tbl2.col = tbl1.col);

如果你不知道哪个表有多余的行或两者都有,你可以在切换表名后重复上面的查询,或者:

SELECT *
FROM   tbl1
FULL   OUTER JOIN tbl2 USING (col)
WHERE  tbl2 col IS NULL OR
       tbl1.col IS NULL;

在后面的帖子中概述基本技术:

另外:uuid 数据类型对于 md5 哈希是有效的:

【讨论】:

    【解决方案2】:

    根据我的经验,NOT IN 子查询需要很长时间。我会通过包容性加入来做到这一点:

    DELETE FROM table1 where ID IN (
    SELECT id FROM table1
    LEFT OUTER JOIN table2 on table1.hashfield = table2.hashfield
    WHERE table2.hashfield IS NULL)
    

    然后对另一张桌子做同样的事情。

    【讨论】:

    • 请注意NOT INNOT EXISTS 原则上不同。 NULL 处理方式不同,这使得 NOT IN 更昂贵。
    【解决方案3】:

    为了扩充现有答案,我使用row() 函数作为连接条件。这允许您比较整行。例如。我查看对称差异的典型查询如下所示

    select *
    from tbl1
    full outer join tbl2 
        on row(tbl1) = row(tbl2)
    where tbl1.col is null
    or    tbl2.col is null
    

    【讨论】:

      【解决方案4】:

      如果您想在不知道哪个表的行数多于其他表的情况下找出差异,您可以尝试使用此选项来获取任一表中存在的所有行:

      SELECT * FROM A
      WHERE NOT EXISTS (SELECT * FROM B) 
        UNION
      SELECT * FROM B
      WHERE NOT EXISTS (SELECT * FROM A)
      

      【讨论】:

        猜你喜欢
        • 2014-01-12
        • 2015-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多