web-dev-qa-db-ja.com

ブールフィールドのインデックス作成

これはおそらく本当に愚かな質問ですが、データベーステーブルのブール型フィールドにインデックスを付けることには大きなメリットがありますか?

非アクティブとしてフラグが付けられた「ソフト削除」レコードなどの一般的な状況を考えると、ほとんどのクエリにはWHERE deleted = 0、そのフィールドに独自のインデックスを付けるのに役立ちますか、それとも、別のインデックスで一般的に検索される他のフィールドと組み合わせる必要がありますか?

70
nickf

番号。

検索され、選択性/カーディナリティが高いフィールドにインデックスを付けます。ブールフィールドのカーディナリティは、ほとんどすべてのテーブルで消去されます。どちらかと言えば、書き込みが遅くなります(非常にわずかな量)。

たぶん、すべてのクエリがソフト削除を考慮に入れたら、それをクラスター化インデックスの最初のフィールドにするでしょうか?

55
Mark Canlas

Deleted_at DATETIME列についてはどうですか? 2つの利点があります。

  1. 名前のような一意の列が必要な場合は、同じ名前のレコードを複数回作成してソフト削除できます(削除された列と名前に一意のインデックスを使用する場合)
  2. 最近削除されたレコードを検索できます。

クエリは次のようになります。

SELECT * FROM xyz WHERE deleted_at IS NULL
17
jhlllnd

特にインデックスをカバーするのに役立つと思います。

もちろん、どのくらい/少しはあなたのデータとクエリに依存しています。

インデックスに関するあらゆる種類の理論を持つことができますが、最終的な答えは、実際のデータを持つデータベース内のデータベースエンジンによって与えられます。そして、しばしばあなたは答えに驚かされます(または私の理論が多​​すぎるかもしれません;)

クエリのクエリプランを調べて、クエリを改善できるかどうか、またはインデックスを改善できるかどうかを判断します。インデックスを変更して、どのような違いがあるかを確認するのは非常に簡単です

6
Brimstedt

ビュー(deleted = 0)を使用していて、このビューから定期的にクエリを実行している場合に役立つと思います。

2
Adriaan Stander

私はあなたのブールフィールドが多くの場合それらを参照するようなものであるなら、別のテーブル、例えばDeletedPages、またはis_deletedのような多くのブール型フィールドを持つSpecialPagesを持つことは理にかなっていると思いますis_hiddenis_really_deletedrequires_higher_userなどの場合、結合を取得してそれらを取得します。

通常、このテーブルのサイズは小さくなり、特にコードの可読性と保守性に関する限り、結合を行うことでいくつかの利点が得られます。そして、このタイプのクエリの場合:

select all pages where is_deleted = 1

次のように実装するとより高速になります。

select all pages where pages 
inner join DeletedPages on page.id=deleted_pages.page_id 

MySQLデータベースのどこかで、カーディナリティが少なくとも3であるフィールドにインデックス付けを機能させる必要があるという説明を読んだと思いますが、これを確認してください。

2
umar

ビットマップインデックスをサポートするデータベース(Oracleなど)を使用している場合、ブール列のそのようなインデックスは、そうでない場合よりもはるかに便利です。

0
Rondo