を含むクエリを記述しようとしていますWHERE isok=1
。名前が示すように、isok
はブールフィールドです(実際にはTINYINT(1) UNSIGNED
、必要に応じて0または1に設定されるa )。
このフィールドのインデックスを作成すると、パフォーマンスが向上しますか?エンジン(この場合はInnoDB)は、インデックスのルックアップのパフォーマンスが向上しますか?
を含むクエリを記述しようとしていますWHERE isok=1
。名前が示すように、isok
はブールフィールドです(実際にはTINYINT(1) UNSIGNED
、必要に応じて0または1に設定されるa )。
このフィールドのインデックスを作成すると、パフォーマンスが向上しますか?エンジン(この場合はInnoDB)は、インデックスのルックアップのパフォーマンスが向上しますか?
回答:
あんまり。あなたはそれを本のように考えるべきです。本に3種類の単語しかなく、それらすべてを索引付けすると、通常のページと同じ数の索引ページができます。
1つの値のレコードが比較的少ない場合は、パフォーマンスが向上します。たとえば、1000件のレコードがあり、そのうちの10件がTRUEの場合、次のように検索すると便利です。isok = 1
Michael Durrantが述べたように、書き込みも遅くなります。
編集:重複の可能性:ブールフィールドのインデックス作成
ここでは、インデックスがある場合でも、レコードが多すぎるとインデックスが使用されないことを説明します。 MySQLは= 1をチェックするときにインデックスを使用しませんが、= 0で使用します
私の経験では、このような質問を見ている人たちは私たちと同じボートにいるので、ブールフィールドのインデックス付けは無意味であると聞いたことがありますが...
約400万行のテーブルがあり、一度に約1000程度しかブールスイッチがフラグされません。これが検索対象です。ブールフィールドにインデックスを追加すると、クエリが桁違いに高速化され、約9秒以上から1秒未満になります。
WHERE my_col > 0
代わりにmy_col = 1
スピードを助けるように見える
実際のクエリと、インデックスとクエリの組み合わせの選択性によって異なります。
ケースA:状態のみでWHERE isok = 1
、他には何もありません。
SELECT *
FROM tableX
WHERE isok = 1
インデックスが十分に選択的である場合(たとえば、100万行あり、1k行のみisok = 1
)、SQLエンジンはおそらくインデックスを使用し、インデックスがない場合よりも高速になります。
インデックスが十分に選択的でない場合(たとえば、100万行あり、100k以上ある場合isok = 1
)、SQLエンジンはおそらくインデックスを使用せず、テーブルスキャンを実行します。
ケースB:状態WHERE isok = 1
など:
SELECT *
FROM tableX
WHERE isok = 1
AND another_column = 17
次に、他のどのインデックスを使用しているかによって異なります。インデックスanother_column
は、おそらくisok
2つの値しか持たないインデックスよりも選択的です。(another_column, isok)
または上のインデックスは(isok, another_column)
さらに良いでしょう。
それはデータの分布に依存します。
厳密にタイプされた1000ページの本があり、私の本の単語は「はい」と「いいえ」だけが何度も繰り返され、ランダムに分布していたとします。「はい」のすべてのインスタンスを丸で囲むように依頼された場合、本の裏にある索引は役に立ちますか?場合によります。
「はい」と「いいえ」が半々ランダムに分布している場合、インデックスを調べても役に立ちません。インデックスを付けると、本がかなり大きくなります。とにかく、最初から始めて、各項目を調べるのではなく、「はい」のすべてのインスタンスを探して、それらを一周するように各ページを進めていきます。インデックスと、インデックスエントリから参照先のページへの参照を取得します。
しかし、たとえば、1000ページの本に「はい」のインスタンスが10個しかなく、それ以外はすべて何百万もない場合、インデックスを使用すると、「はい」の10個のインスタンスを見つけて循環させるのにかかる時間を大幅に節約できます。 。
データベースでも同じです。それが50:50の分布である場合、インデックスは役に立ちません-データベースエンジンは、データを最初から最後まで(フルテーブルスキャン)プラウするだけの方がよく、インデックスはデータベースを大きくします。書き込みと更新が遅い。しかし、(このスレッドのoucilのように)4000:1の分布のようなものである場合、探している項目の4000分の1であれば、インデックスシークによって大幅に高速化できます。
いいえ、通常はありません。
通常、フィールドは選択性/カーディナリティが高い場合に検索用にインデックスを付けます。ブールフィールドのカーディナリティは、ほとんどのテーブルで非常に低くなっています。また、書き込みが部分的に遅くなります。
実際、これは実行するクエリによって異なります。しかし、一般的にはそうです。また、他のタイプのフィールドにインデックスを付けることもできます。
はい、インデックスはパフォーマンスを向上させます。インデックスの有無にかかわらずEXPLAINの出力を確認してください。
ドキュメントから:
インデックスは、特定の列の値を持つ行をすばやく見つけるために使用されます。インデックスがない場合、MySQLは最初の行から始めて、関連する行を見つけるためにテーブル全体を読み取る必要があります。テーブルが大きいほど、コストが高くなります。テーブルに問題の列のインデックスがある場合、MySQLはすべてのデータを調べる必要なく、データファイルの中央でシークする位置をすばやく決定できます。
私はそれがインデックスがないだろうと言っても安全だと思うの減少だけそれから利益を持っているので、この場合には、パフォーマンスを。
TINYINT(1) UNSIGNED
列、データのサイズは小さくなります。