SQLパフォーマンス UNIONとORの比較
質問
最適化に関する記事の一部を読んだだけなのですが セグメンテーションが失敗しました。 が発生しました。
を使用したSQL置換文の場合
OR
をUNION
: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 クエリプロファイラ で両方の方法を試し、そのパフォーマンスを比較することです。
関連
-
MySQLで正規表現を使う 詳細
-
[解決済み] mysqladminのフラッシュホストでブロックを解除する方法
-
[解決済み] SQL ServerでSELECTからUPDATEする方法とは?
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] PHPでSQLインジェクションを防ぐにはどうしたらいいですか?
-
[解決済み] MySQLでコマンドラインを使用してSQLファイルをインポートするにはどうすればよいですか?
-
[解決済み] SQLテーブルで重複する値を検索する
-
[解決済み] 0.1fを0にすると、なぜ10倍もパフォーマンスが落ちるのですか?
-
[解決済み] UNIONとUNION ALLの違いは何ですか?
-
[解決済み】SQL Serverで既存のテーブルにデフォルト値を持つカラムを追加する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
MySqlの整数インデックスと文字列インデックスの失敗または暗黙の変換問題
-
MySQLのWhereの使用方法について説明します。
-
[解決済み】マルチパート識別子をバインドできませんでした。
-
SQLステートメントエラーです。オペランドには 1 つのカラムを含める必要があります [括弧を追加せずに複数のフィールドをクエリする
-
Mysqlの使用中に発生したエラーの一部
-
[解決済み] ユーザー 'root'@'localhost' (パスワード: YES を使用) のアクセス拒否 - 特権がない?
-
[解決済み] なぜ SQLAlchemy の count() は生のクエリよりずっと遅いのでしょうか?
-
[解決済み] KEYキーワードは何を意味するのか?
-
[解決済み] SQLを使用してSUMとSUBTRACTを行うには?
-
[解決済み] SQLでカラムに最大値を持つ行のみを選択する [重複]。