これはおそらく本当に愚かな質問ですが、データベーステーブルのブール型フィールドにインデックスを付けることには大きなメリットがありますか?
非アクティブとしてフラグが付けられた「ソフト削除」レコードなどの一般的な状況を考えると、ほとんどのクエリにはWHERE deleted = 0
、そのフィールドに独自のインデックスを付けるのに役立ちますか、それとも、別のインデックスで一般的に検索される他のフィールドと組み合わせる必要がありますか?
番号。
検索され、選択性/カーディナリティが高いフィールドにインデックスを付けます。ブールフィールドのカーディナリティは、ほとんどすべてのテーブルで消去されます。どちらかと言えば、書き込みが遅くなります(非常にわずかな量)。
たぶん、すべてのクエリがソフト削除を考慮に入れたら、それをクラスター化インデックスの最初のフィールドにするでしょうか?
Deleted_at DATETIME列についてはどうですか? 2つの利点があります。
クエリは次のようになります。
SELECT * FROM xyz WHERE deleted_at IS NULL
特にインデックスをカバーするのに役立つと思います。
もちろん、どのくらい/少しはあなたのデータとクエリに依存しています。
インデックスに関するあらゆる種類の理論を持つことができますが、最終的な答えは、実際のデータを持つデータベース内のデータベースエンジンによって与えられます。そして、しばしばあなたは答えに驚かされます(または私の理論が多すぎるかもしれません;)
クエリのクエリプランを調べて、クエリを改善できるかどうか、またはインデックスを改善できるかどうかを判断します。インデックスを変更して、どのような違いがあるかを確認するのは非常に簡単です
ビュー(deleted = 0)を使用していて、このビューから定期的にクエリを実行している場合に役立つと思います。
私はあなたのブールフィールドが多くの場合それらを参照するようなものであるなら、別のテーブル、例えばDeletedPages、またはis_deleted
のような多くのブール型フィールドを持つSpecialPagesを持つことは理にかなっていると思いますis_hidden
、is_really_deleted
、requires_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であるフィールドにインデックス付けを機能させる必要があるという説明を読んだと思いますが、これを確認してください。
ビットマップインデックスをサポートするデータベース(Oracleなど)を使用している場合、ブール列のそのようなインデックスは、そうでない場合よりもはるかに便利です。