我在 Postgres 中有两个类似的表,只有一个 32 字节的拉丁字段(简单的 md5 哈希)。两个表都有约 30,000,000 行。表格差别不大(10-1000行不一样)
Postgres 是否可以找到这些表之间的差异,结果应该是我上面描述的 10-1000 行。
这不是一个真正的任务,我只是想知道 PostgreSQL 如何处理类似 JOIN 的逻辑。
我在 Postgres 中有两个类似的表,只有一个 32 字节的拉丁字段(简单的 md5 哈希)。两个表都有约 30,000,000 行。表格差别不大(10-1000行不一样)
Postgres 是否可以找到这些表之间的差异,结果应该是我上面描述的 10-1000 行。
这不是一个真正的任务,我只是想知道 PostgreSQL 如何处理类似 JOIN 的逻辑。
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 哈希是有效的:
为了增加现有答案,我使用该row()
函数作为连接条件。这允许您比较整行。例如,我查看对称差异的典型查询如下所示
select *
from tbl1
full outer join tbl2
on row(tbl1) = row(tbl2)
where tbl1.col is null
or tbl2.col is null
如果您想在不知道哪个表的行数多于其他表的情况下找出差异,您可以尝试使用此选项来获取任一表中存在的所有行:
SELECT * FROM A
WHERE NOT EXISTS (SELECT * FROM B)
UNION
SELECT * FROM B
WHERE NOT EXISTS (SELECT * FROM A)
根据我的经验,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)
然后对另一张桌子做同样的事情。