RDBMS 专门用于排序等操作。在数据库之外执行此操作几乎不会在性能上接近。用 SQL 来做!
这将完成工作(在更新中简化):
SELECT t1.usr || '-' || t2.usr, count(*) AS ct
FROM usr_grp t1
JOIN usr_grp t2 USING (grp_id)
WHERE t2.usr > t1.usr -- prevent dupes and get sorted pair
GROUP BY t1.usr, t2.usr;
正如您所说,根据您有多少重叠,这可能会产生大量的行。所以这永远不会很快。
提出了一个问题:产生数百万行没人能处理的目的是什么?你确定,这个操作一开始就有意义吗?
为了让它更快,你可以..
- 升级! PostgreSQL 8.4 现在已经过时了。特别是 PostgreSQL 9.2 专注于大数据。对于这样的工作,您可以期待更好的表现。没有人应该运行 8.4.0
。仅出于安全原因,您也错过了许多错误修复。当前的版本是 8.4.17。我引用链接的网站:
我们始终建议所有用户针对正在使用的主要版本运行最新的可用次要版本。
- 为用户使用
integer
as 代理键,因此您只在usr_grp
. 使表和索引更小,处理速度更快。如果 n:m table ( usr_grp
) 的基数比 table 大得多usr
,这应该会更快,即使这意味着额外的连接。
SELECT u1.usr || '-' || u2.usr, count(*) AS ct
FROM usr_grp t1
JOIN usr_grp t2 USING (grp_id)
JOIN usr u1 ON t1.usr_id = u1.usr_id
JOIN usr u2 ON t2.usr_id = u2.usr_id
WHERE t2.usr_id > t1.usr_id
GROUP BY u1.usr_id, u2.usr_id;
CREATE INDEX usr_grp_gu_idx ON usr_grp(grp_id, usr_id);
测试用例
我获取了@OldCurmudgeon为他的测试用例报告的数字,并在 PostgreSQL 中创建了一个可比较的测试用例。
-> SQLfiddle演示。
在这个公共测试数据库中~ 250 毫秒。
结果未排序(否ORDER BY
),因为尚未指定。
相比2.5 分钟,报告如下。系数 600。