[英]A more efficient way to sum the difference between columns in postgres?
对于我的应用程序,我有一个包含以下三列的表: user, item, value
以下是一些示例数据:
user item value
---------------------
1 1 50
1 2 45
1 23 35
2 1 88
2 23 44
3 2 12
3 1 27
3 5 76
3 23 44
对于给定的用户,我需要做的是针对其他所有人的值执行简单的算术运算。
假设我想将用户 1 与其他所有人进行比较。 计算如下所示:
first_user second_user result
1 2 SUM(ABS(50-88) + ABS(35-44))
1 3 SUM(ABS(50-27) + ABS(45-12) + ABS(35-44))
这是目前我程序中的瓶颈。 例如,我的许多查询开始需要 500 多毫秒,而这个算法大约需要 95% 的时间。
我的数据库中有很多行,它是 O(n^2) (它必须将所有用户 1 的值与其他所有人的匹配值进行比较)
我相信我只有两种选择来提高效率。 首先,我可以缓存结果。 但是结果表会很大,因为需要 NxN 空间,并且值需要相对新鲜。
第二种方法是使算法更快。 我搜索了“postgres SIMD”,因为我认为 SIMD 听起来是优化它的完美解决方案。 我找到了一些相关链接,例如this和this ,但我不确定它们是否适用于此。 此外,它们似乎都有 5 年左右的历史并且相对无人维护。
Postgres 是否支持这种功能? 您可以在哪里“矢量化”一列,或者可能导入或启用某些扩展或功能,以允许您对多行快速执行这些类型的基本算术运算?
我不确定你从哪里得到 O(n^2) 。 您需要查找用户 1 的行,然后为其他所有人读取数据。 假设项目很少,用户很多,这基本上是 O(n),其中“n”是表中的行数。
查询可以表述为:
select t1.user, t.user, sum(abs(t.value - t1.value))
from t left join
t t1
on t1.item = t.item and
t1.user <> t.user and
t1.user = 1
group by t1.user, t.user;
对于此查询,您需要t(item, user, value)
上的索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.