在 PostgreSQL 中查找两个大表之间的差异

Posted

技术标签:

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

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

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

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

【问题讨论】:

看看这个How to compare two tables in postgres和这个加速差异How can I speed up a diff between tables? 【参考方案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;

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

Select rows which are not present in other table

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

Convert hex in text representation to decimal number Would index lookup be noticeably faster with char vs varchar when all values are 36 chars

【讨论】:

【参考方案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)

【讨论】:

以上是关于在 PostgreSQL 中查找两个大表之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

如何获得 PostgreSQL 中的两个平均值之间的差异,平均值在列上,最终表按两列分组?

在 sql 中查找两个透视列之间的差异

在 pyspark sql 中查找两个时间戳之间的差异

查找熊猫中两个日期之间差异的最简单方法

awk 查找两个文件中第二个字段之间的差异

计算Postgresql中两列之间的运行差异