我有一个表格,其中包含 bit(2000)类型的 vector 列。 db引擎如何处理此值的操作 AND 和 OR ?它是否只是分成32位块(或分别为64位),然后分别比较每个块,最后简单地将结果连接在一起?或者它只是作为两个字符串处理?
我的观点是预测,哪个用例会更快。我得到了一个键值数据(用户项)。
userID | itemID
U1 | I1
U1 | Ix
Un | Ij
对于每个用户,我想计算n个最近邻居的列表(例如,使用jaccard index)。
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个有效位。我认为,解析整个bitvector只是为了找到有效位需要更多的计算资源,而不是简单地将user1的10个值与user2的10个值相互比较。
使用长位向量是否更快,这些位向量的位数设置为1,或者更好地将原始值用作集合并将两个集合在一起? (一套最多10件)
我同时使用psql v8.2和v9.x
答案 0 :(得分:5)
位类型的位操作在内部处理为呃位操作。以下是“和”代码的作用,例如:
p1 = VARBITS(arg1);
p2 = VARBITS(arg2);
r = VARBITS(result);
for (i = 0; i < VARBITBYTES(arg1); i++)
*r++ = *p1++ & *p2++;
(所以它实际上是8位块。)
所以我觉得这应该很快。
答案 1 :(得分:3)
源代码似乎逐字节进行比较。在the PostgreSQL source code中搜索“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++;