1. ホーム
  2. mysql

SQLパフォーマンス UNIONとORの比較

2023-10-05 04:13:08

質問

最適化に関する記事の一部を読んだだけなのですが セグメンテーションが失敗しました。 が発生しました。

を使用したSQL置換文の場合 ORUNION :

select username from users where company = ‘bbc’ or company = ‘itv’;

になります。

select username from users where company = ‘bbc’ union
select username from users where company = ‘itv’;

ざっくりとしたものから EXPLAIN :

使用方法 OR :

<イグ

使用方法 UNION :

<イグ

これはつまり UNION 倍の仕事をする ?

私は UNION は特定の RDBMS や特定のテーブルスキーマに対してより高いパフォーマンスを発揮するかもしれませんが、これは のように というのは、著者の提案のとおりです。

質問

私は間違っているのでしょうか?

どのように解決するのですか?

あなたが読んだ記事は悪い例を使用しているか、またはあなたが彼らのポイントを誤解しているかのどちらかです。

select username from users where company = 'bbc' or company = 'itv';

と同等である。

select username from users where company IN ('bbc', 'itv');

MySQL は company にインデックスを使用することができます。 UNIONを行う必要はありません。

よりトリッキーなケースは OR を含む条件である場合です。 異なる の列を含む。

select username from users where company = 'bbc' or city = 'London';

にインデックスがあるとします。 company にインデックスがあり city . MySQL は通常、与えられたクエリでテーブルごとに 1 つのインデックスしか使用しないことを考えると、どのインデックスを使用すべきでしょうか? のインデックスを使用する場合 company のインデックスを使用する場合、テーブルスキャンを行い、行を見つける必要があります。 city がロンドンである行を見つけるためにテーブルスキャンを行う必要があります。 のインデックスを使用すると city のインデックスを使用する場合、テーブルスキャンを行わなくてはなりません。 company が bbc である行をテーブルスキャンする必要があります。

UNION の解決策は、このようなケースに対応するものです。

select username from users where company = 'bbc' 
union
select username from users where city = 'London';

これで、各サブクエリはその検索にインデックスを使うことができ、サブクエリの結果は UNION .


匿名ユーザーが上記の私の回答に対して編集を提案しましたが、モデレータがその編集を拒否しました。それは編集ではなく、コメントであるべきでした。 提案された編集の主張は、UNIONが重複行を排除するために結果セットをソートしなければならないということでした。 これによりクエリの実行速度が遅くなり、インデックスの最適化が無駄になります。

私の回答は、UNION が起こる前に、インデックスが結果セットを少数の行に減らすのに役立つというものです。 UNION は実際に重複を排除しますが、それを行うには、小さな結果セットを並べ替えるだけでよいのです。 WHERE句がテーブルのかなりの部分にマッチしている場合、UNION時のソートは単にテーブルスキャンを行うのと同じくらいコストがかかる場合があります。 しかし、インデックス検索によって結果セットが減少することはより一般的なので、ソートはテーブルスキャンよりもはるかにコストが低くなります。

この違いは、テーブル内のデータ、および検索される用語に依存します。 与えられたクエリに対する最適な解決策を決定する唯一の方法は、両方のメソッドを MySQL クエリプロファイラ で両方の方法を試し、そのパフォーマンスを比較することです。