あなたが読んだ記事は悪い例を使っていたか、またはそれらのポイントを誤解していました。
select username from users where company = 'bbc' or company = 'itv';
これは次と同等です。
select username from users where company IN ('bbc', 'itv');
company
MySQL は、このクエリにインデックスを使用できます。UNION を行う必要はありません。
よりトリッキーなケースは、 2 つの異なる列OR
を含む条件がある場合です。
select username from users where company = 'bbc' or city = 'London';
にインデックスがcompany
あり、 に別のインデックスがあるとしcity
ます。MySQL は通常、特定のクエリでテーブルごとに 1 つのインデックスのみを使用するため、どのインデックスを使用する必要がありますか? のインデックスを使用する場合でも、がロンドンcompany
の行を見つけるためにテーブル スキャンを実行する必要があります。city
のインデックスを使用する場合、bbccity
の行に対してテーブル スキャンを実行する必要があります。company
解決策は、このUNION
タイプのケースです。
select username from users where company = 'bbc'
union
select username from users where city = 'London';
これで、各サブクエリは検索にインデックスを使用できるようになり、サブクエリの結果はUNION
.
匿名ユーザーが上記の回答の編集を提案しましたが、モデレーターが編集を拒否しました。編集ではなく、コメントであるべきでした。提案された編集の主張は、重複行を排除するために UNION が結果セットをソートする必要があるというものでした。これにより、クエリの実行が遅くなるため、インデックスの最適化が面倒になります。
私の回答は、UNION が発生する前に、インデックスが結果セットを少数の行に減らすのに役立つということです。実際、UNION は重複を排除しますが、そのためには、小さな結果セットを並べ替えるだけで済みます。WHERE 句がテーブルの大部分と一致する場合があり、UNION 中の並べ替えは単にテーブル スキャンを実行するのと同じくらいコストがかかります。しかし、結果セットがインデックス付き検索によって削減されることはより一般的であるため、並べ替えはテーブル スキャンよりもはるかにコストがかかりません。
違いは、テーブル内のデータと検索される用語によって異なります。特定のクエリの最適なソリューションを決定する唯一の方法は、MySQL クエリ プロファイラーで両方の方法を試して、それらのパフォーマンスを比較することです。