2

bit(2000)型の列ベクトルを持つテーブルがあります。dbエンジンは、この値に対する操作ANDおよびORをどのように処理しますか?単純に32ビットチャンク(またはそれぞれ64)に分割してから、各チャンクを個別に比較し、最終的に結果を単純に連結しますか?それとも単に2つの文字列として処理しますか?

私のポイントは、どちらのユースケースがより速いかを予測することです。Key-Valueデータ(user-item)を取得しました。

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

ユーザーごとに、n個の最近傍のリストを計算します(たとえば、ジャッカード係数を使用)。

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に設定されたビットが非常に少ない長いビットベクトルを使用する方が速いですか、それとも元の値をセットとして使用して2つのセットを比較する方が良いですか?(セットは最大10アイテム)

私はpsqlv8.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 に答える