2

我有一个带有bit(2000)类型的列向量的表。db 引擎如何处理此值的ANDOR操作?它是否只是简单地划分为 32 位块(或分别为 64 位),然后分别比较每个块,最后简单地将结果连接在一起?或者它只是作为两个字符串处理?

我的意思是预测哪个用例会更快。我有一个键值数据(用户项)。

userID | itemID
U1     | I1
U1     | Ix
Un     | Ij

对于每个用户,我想计算 n 个最近邻居的列表(例如,使用jaccard 索引)。

select my_jaccard(select itemID from table where userID=U1,select itemID from table where userID=U2)

我的解决方案 - 我将输入数据解析为用户向量表,其中向量的类型为 bit(2000),在表示特定项目的位置上为 1。

userID | vector
U1     | 00.......01
U1     | 0..1.....00
Un     | 00..1..1..0

在这张桌子上我只是做

select vector1&vector2

关键是每个用户最多只有 10 条记录的所有项目,即向量最多有 10 个活动位。我认为,解析整个位向量只是为了找到活动位需要更多的计算资源,而不是简单地将 user1 的这 10 个值与 user2 的 10 个值相互比较。

使用将很少位设置为 1 的长位向量是否更快,或者将原始值用作一个集合并将两个集合一起比较是否更好?(一套最多10个项目)

我同时使用 psql v8.2 和 v9.x

4

2 回答 2

5

对位类型的位操作在内部处理为,呃,位操作。以下是“and”代码的作用,例如:

p1 = VARBITS(arg1);
p2 = VARBITS(arg2);
r = VARBITS(result);
for (i = 0; i < VARBITBYTES(arg1); i++)
    *r++ = *p1++ & *p2++;

(所以它实际上是 8 位块。)

所以我认为这应该很快。

于 2013-01-08T17:04:11.253 回答
3

源代码似乎是逐字节比较的。在 PostgreSQL 源代码中搜索函数“bit_and”和“bit_or”。(我似乎没有直接链接到函数的自然方式。)

bit_and() 的摘录,varbit.c 的第 1205 到 1209 行

p1 = VARBITS(arg1);
p2 = VARBITS(arg2);
r = VARBITS(result);
for (i = 0; i < VARBITBYTES(arg1); i++)
    *r++ = *p1++ & *p2++;
于 2013-01-08T17:04:17.923 回答