在 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 哈希是有效的:
【讨论】:
【参考方案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 IN
与NOT 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 中查找两个大表之间的差异的主要内容,如果未能解决你的问题,请参考以下文章