次のような3つの列と数千のレコードを持つテーブルがあるとします。
id # primary key
name # indexed
gender # not indexed
そして、「アレックスという名前のすべての男性」、つまり特定の名前と特定の性別を見つけたいと思います。
ナイーブな方法(select * from people where name='alex' and gender=2
)はここで十分ですか?または、名前のサブクエリなど、より最適な方法はありますか?
次のような3つの列と数千のレコードを持つテーブルがあるとします。
id # primary key
name # indexed
gender # not indexed
そして、「アレックスという名前のすべての男性」、つまり特定の名前と特定の性別を見つけたいと思います。
ナイーブな方法(select * from people where name='alex' and gender=2
)はここで十分ですか?または、名前のサブクエリなど、より最適な方法はありますか?
名前に一致する数千のレコードがなく、実際に男性であるレコードはわずかであると仮定すると、インデックス onname
で十分です。一般に、カリーナリティがほとんどないフィールドにインデックスを付けるべきではありません (可能な値が 2 つしかないということは、行の 50% に一致することを意味し、インデックスを使用することは正当化されません)。
私が考えることができる唯一の有用な例外は、名前と性別のみを選択している場合であり、両方をインデックスに入れると、 を実行できますindex-covered query
。これは、インデックスで行を選択してからデータを取得するよりも高速ですテーブル。
インデックスの作成がオプションではない場合、またはテーブルに大量のデータがある場合 (または、インデックスがあってもペースを速めたい場合) に従ってテーブルを並べ替えると、大きな影響が生じることがよくあります。一緒にグループ化しているデータに。
私の部門の KPI をまとめるためのクエリを実行中です。すべてがうまくインデックス化されていたにもかかわらず、引き出されたデータはまだ数ギグのテーブルを検索していました。これは、クエリがすべての正しい行をまとめて集計している間に、多くのディスク アクセスが発生することを意味します。を使用してテーブルを並べ替えたところalter table tableName order by column1, column2;
、クエリは約 15 秒から 3 秒未満でデータを返すようになりました。そのため、データの物理的な収集は、テーブルにインデックスが付けられていて、DB がそれを取得する場所を正確に認識している場合でも、大きな影響を与える可能性があります。データベースが必要なものすべてに簡単にアクセスできるようにデータを配置すると、パフォーマンスが向上します。
より良い方法は、複合インデックスを使用することです。
すなわち
CREATE INDEX <some name for the index> ON <table name> (name, gender)
次に、WHERE
句で名前と性別の両方に使用できます。