アップデート:
パフォーマンスの詳細については、ブログの次のエントリを参照してください。
SELECT * FROM table WHERE field & number = number
SELECT * FROM table WHERE field | number = number
このインデックスは、次の2つの方法で効果的です。
- 初期のテーブルスキャンを回避するため(比較する値がインデックス自体に含まれているため)
上記のクエリのどちらの条件もsargableではありません。これは、インデックスが範囲スキャンに使用されないことです(現在の条件では)。
ただし、ポイント1
は引き続き保持されるため、インデックスが役立つ場合があります。
たとえば、テーブル100
に平均で1行あたりのバイト数と1,000,000
レコードが含まれている場合、テーブルスキャンではデータをスキャンする必要があり100 Mb
ます。
インデックス(4
-byteキー、 -byte行ポインター、および内部オーバーヘッドを含む)がある場合、フィルターが成功すると、クエリはデータとテーブルからの追加データ6
のみをスキャンする必要があります。10 Mb
- 条件が選択的でない場合(条件に一致する可能性が高い場合)、テーブルスキャンはより効率的です。
- 条件が選択的である場合(条件に一致する可能性が低い場合)、インデックススキャンはより効率的です。
これらのクエリは両方とも、インデックス全体をスキャンする必要があります。
ただし、クエリを書き直すAND
ことで、インデックスの範囲からもメリットを得ることができます。
この状態:
field & number = number
セットの最上位ビットもnumber
設定されている場合にのみ、フィールドに一致することができfield
ます。
そして、この追加の条件をクエリに指定する必要があります。
SELECT *
FROM table
WHERE field & number = number
AND field >= 0xFFFFFFFF & ~((2 << FLOOR(LOG(2, 0xFFFFFFFF & ~number))) - 1)
これは、粗いフィルタリングの範囲と細かいフィルタリングの条件を使用します。
number
最後に未設定のビットが多いほど良いです。