【问题标题】:how does postgres handle the bit data type?postgres 如何处理位数据类型?
【发布时间】:2013-01-09 01:04:17
【问题描述】:

我有一个表格,其中有一列 vector 类型为 bit(2000)。 db 引擎如何处理对这些值的 ANDOR 操作?它是否只是简单地划分为 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 个活动位。我认为,解析整个位向量只是为了找到活动位需要更多的计算资源,而不是简单地将 user1 的这 10 个值与 user2 的 10 个值相互比较。

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

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

【问题讨论】:

  • 为什么是过时的 v8.2?并且需要在 v9.x 中指定 x 来声明 Postgres 版本。
  • @ErwinBrandstetter:谢谢,计算是否取决于版本?我使用 8.2,因为它是一个生产实例,我无法更改。 v9.x 可以是任何人,因为这是一个测试实例,我可以将其更改为更适合这种情况的任何一个。如果答案取决于版本,我无论如何都需要知道差异所以让我们假设所有版本都来自 8-9.x

标签: postgresql data-mining vectorization computation


【解决方案1】:

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

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

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

所以我认为这应该很快。

【讨论】:

    【解决方案2】:

    源代码似乎是逐字节比较的。在 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++;
    

    【讨论】:

    • 感谢您的评论,我将下面的答案标记为已接受,你们俩都提供了我需要的相同信息,但彼得早了 6 秒 :)
    • 6 秒?我责怪康卡斯特。
    猜你喜欢
    • 2016-02-04
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 2018-11-16
    • 2022-11-25
    相关资源
    最近更新 更多