web-dev-qa-db-ja.com

MySQLのBIT(n)属性にインデックスを作成することは意味がありますか?

私は非常に具体的なものに取り組んでおり、BIT(n)属性を使用して効率的に検索する必要があります。 nは通常2の累乗ではありません。

MySQLでBIT属性がインデックスに対応していないというインターネットでの言及がいくつかありました。それ以上の詳細なしで。

したがって、問題は、MySQLインデックスがBIT(n)属性で適切に機能するか、またはnを32に制限し、代わりにINTを使用するなど、他の方法を見つけた方がよいでしょうか。

7
bazzilic

をクエリしている場合を除き、 ビット列に格納されている値全体との完全一致、 インデックスは一般的に使用できないため、役に立ちません。あなたがそうである可能性はほとんどありません。

ビットマップ値を格納し、1つ以上のビットの状態に基づいてクエリを実行するときにインデックスを使用できない理由には、MySQLで一般的に利用可能なインデックスタイプが正確な値または範囲のマッチングにのみ役立つという事実が含まれます。ビットごとの比較は、それらのどちらにも当てはまりません。

この制限の性質上、整数データ型またはSETデータ型を使用する場合にも当てはまります。

たとえば、8ビットの数値の上位ビットの状態をテストすることは、数値が128以上であるかどうかをテストすることと同じです。これは実際に範囲一致であり、Bツリーインデックスを使用して達成できますが、このテストにインデックスを利用する場合、オプティマイザーは、実際に何を求めているのかを「本当に」尋ねているのがWHERE bin_col&b'10000000 '...オプティマイザーが認識しないことを理解する必要があります。それ。

MySQLのBITカラムは実際には整数データよりもCHAR/BINARYカラムに類似しているため、ビットマップ値を保存する私の傾向はUNSIGNED [何か] INTカラムを使用することですが、これは最終的にはアプリケーションだけでなくアプリケーションにも依存します。ストレージエンジン。

MyISAMはどうやら異なるビット列を生の行データに一緒に格納するため、8/16/32/64のインクリメントも使用しない場合、BITとINTを使用すると、小さなストレージの利点が得られる可能性がありますが、既にMyISAMを使用しているので、これを使用することを検討するのに十分な利点だとは思わないでしょう。

MEMORYおよびInnoDBエンジンは、BIT列に必要なビット数を保持できる最小の標準整数サイズを割り当てます。

SETデータ型は、ビットに定義するラベルの数に応じて、値を1、2、3、4、または8バイトの符号なし整数としても格納します。格納されているビットマップデータを表示しているときは、結果を整数にキャストしないで選択すると(SELECT column_name + 0を使用して明示的または暗黙的に)、コンマ区切りで返されるため、目が楽です。 「オン」に設定されているビットのラベルのリスト...クエリの最適化は提供されませんが、生の整数を使用する場合と比較して、実際のペナルティなしにビットをラベルに拡張する機能が強化されます。カラム。

6