「WHERE + OR」と「UNION」は同値になります。
であれば、どちらを使った方が良いでしょうか。
WHERE + OR
- ORを使ってしまうとインデックスが使われません。
- ただ、テーブルへのアクセス回数を減らすことが可能です。
1 2 3 4 5 |
SELECT * FROM テーブル名 WHERE (カラム1 = "A") OR (カラム2 = "A") OR (カラム3 = "A") |
上記SQLの実行計画を見ればわかりますが、インデックススキャンではなくフルテーブルスキャンが使われることになります。ただ、テーブルには1度のアクセスですみます。
UNION
- インデックスを使わせることが可能です。
- テーブルへのアクセス回数が増えます。
1 2 3 4 5 6 7 8 |
SELECT * FROM テーブル名 WHERE (カラム1 = "A") UNION SELECT * FROM テーブル名 WHERE (カラム2 = "A") UNION SELECT * FROM テーブル名 WHERE (カラム3 = "A") |
上記例で言えば、カラム1、カラム2、カラム3に対してCREATE INDEXにてインデックスを付与すれば各3回のWHERE句のSELECT文の実行をインデックスで高速化することが可能です。(その分テーブルには3回アクセスすることになります。)
結論
「1つのテーブルをフルスキャンする方が速い」か、「複数のテーブルに対してインデックススキャンをして組み合わせる方が速い」かのどちらかになります。以下のような状況によって使い分けましょう。
- テーブル全体の行数
- 検索条件の選択率(レコードのヒット率)
テーブルの行数が大きく、検索条件の選択率が小さい場合はインデックススキャンの効果がかなり高い状況になるのでWHERE+ ONよりもUNIONの方が優れたチョイスになります。
CASE式を使った高速化
また、CASE式が使える場合(同じテーブルへのアクセスの場合)は一つのテーブルへのアクセス かつ インデックススキャンを行うことが可能なためできるだけCASE式を使うようにしましょう。
1 2 3 4 5 |
SELECT * FROM テーブル名 WHERE CASE WHEN カラム1 = "A" THEN カラム1 = "A" WHEN カラム2 = "A" THEN カラム2 = "A" WHEN カラム3 = "A" THEN カラム3 = "A" END |
この記事へのコメントはありません。