5.11.2 OR条件に関する等価変換(OR条件の外側への抜き出し)
OR条件中に同じ条件が指定されている場合※,同じ条件をOR条件の外側に抜き出す等価変換が実行されます。同じ条件をOR条件の外側に抜き出すと,検索範囲を絞り込むための条件として有効に利用できることがあります。また,OR条件中の同じ条件が1つに集約されるため,条件評価の負荷が軽減されることがあります。
- 注※
-
ANYを指定した配列要素参照(識別番号は省略)が探索条件に指定されている場合は,探索条件が同じであっても等価変換は実行されません。具体例については,「(2) 等価変換されない例」の「(d) 例4」を参照してください。
- 重要
-
-
WHERE句の探索条件,更新系SQLのWHERE探索条件,結合表のON 探索条件,およびHAVING句の探索条件に指定したOR条件が等価変換の対象になります。
-
探索条件が等価変換された場合,検索時に使用されるインデクスは等価変換後の探索条件を基に決定されます。
-
等価変換の例を次に示します。例中のC1,C2,C3は列名を意味しています。
- 〈この項の構成〉
(1) 等価変換される例
(a) 例1
- [説明]
-
OR条件の両側に「"C1" = 100」という同じ条件があるため,「"C1" = 100」がOR条件の外側に抜き出されます。
(b) 例2
- [説明]
-
OR条件の両側に「"C1" < CURRENT_DATE」という同じ条件があるため,「"C1" < CURRENT_DATE」がOR条件の外側に抜き出されます。
(c) 例3
- [説明]
-
OR条件の両側に「"T1"."C1" = "T2"."C1"」という同じ条件があるため,「"T1"."C1" = "T2"."C1"」がOR条件の外側に抜き出されます。
(d) 例4
- [説明]
-
OR条件の両側に「"C1" IS NULL」という同じ条件があるため,「"C1" IS NULL」がOR条件の外側に抜き出されます。
(e) 例5
- [説明]
-
OR条件の両側に「"C1" IN (100,200,300)」という同じ条件があるため,「"C1" IN (100,200,300)」がOR条件の外側に抜き出されます。
(f) 例6
- [説明]
-
OR条件の両側に「"C1" BETWEEN 100 AND 300」という同じ条件があるため,「"C1" BETWEEN 100 AND 300」がOR条件の外側に抜き出されます。
(g) 例7
- [説明]
-
OR条件中に指定した条件がすべて「"C1" = 100」のため,=条件に等価変換されます。
(h) 例8
- [説明]
-
OR条件中に指定した条件がすべて「"C1" <> 100」のため,<>条件に等価変換されます。
(i) 例9
- [説明]
-
OR条件の両側に「"C1_ARRAY"[ANY(1)] = 100」という同じ条件があるため,「"C1_ARRAY"[ANY(1)] = 100」がOR条件の外側に抜き出されます。
(j) 例10
- [説明]
-
OR条件の両側に「("C1","C2") IN ((1,2),(3,4))」という同じ条件があるため,「("C1","C2") IN ((1,2),(3,4))」がOR条件の外側に抜き出されます。
(2) 等価変換されない例
(a) 例1
- [説明]
-
「"T1"."C1" = "T2"."C1"」と「"T2"."C1" = "T1"."C1"」は,異なる条件と見なされるため,等価変換されません。
(b) 例2
- [説明]
-
OR条件の両側に「"C1" = 100」という同じ条件がありますが,NOT条件中に指定されたOR条件の場合は,等価変換されません。
(c) 例3
- [説明]
-
OR条件の両側に「"C1" = 100 OR "C1" > 200」という同じ条件がありますが,AND条件に指定されたOR条件の場合は,等価変換されません。
(d) 例4
- [説明]
-
OR条件の両側に「"C1_ARRAY"[ANY] = 100」という同じ条件がありますが,配列要素参照に識別番号が指定されていないため,HADBが各配列要素参照に異なる識別番号を割り振ります。そのため,指定された探索条件は同じではないと判定されて,等価変換されません。
(3) 等価変換の規則
-
比較述語で次に示す形式の場合は,OR条件中の条件をOR条件の外側に抜き出します。
{列指定|列指定[ANY〔(識別番号)〕]} 比較演算子 {定数|日時情報取得関数|ユーザ情報取得関数}
{定数|日時情報取得関数|ユーザ情報取得関数} 比較演算子 {列指定|列指定[ANY〔(識別番号)〕]}
{列指定|列指定[ANY〔(識別番号)〕]}※ 比較演算子 {列指定|列指定[ANY〔(識別番号)〕]}※
- 注※
-
列指定,または配列値式が列指定のANYを指定した配列要素参照が左右逆に指定されている場合は,異なる条件と見なされて等価変換されません(「(2) 等価変換されない例」の「(a) 例1」を参照)。
-
NULL述語で次に示す形式の場合は,OR条件中の条件をOR条件の外側に抜き出します。
列指定※ IS 〔NOT〕 NULL
- 注※
-
列指定に配列型の列が指定されている場合は,OR条件の外側への抜き出しは行われません。
-
行値構成子を指定していないIN述語で次に示す形式の場合は,OR条件中の条件をOR条件の外側に抜き出します。
{列指定|列指定[ANY〔(識別番号)〕]} 〔NOT〕 IN ({定数|日時情報取得関数|ユーザ情報取得関数} 〔,{定数|日時情報取得関数|ユーザ情報取得関数}〕…)
-
行値構成子を指定しているIN述語で次に示す形式の場合は,OR条件中の条件をOR条件の外側に抜き出します。
行値構成子1 〔NOT〕 IN (行値構成子2 〔,行値構成子2〕…) 行値構成子1::=(列指定 〔,列指定〕…) 行値構成子2::=({定数|日時情報取得関数|ユーザ情報取得関数} 〔,{定数|日時情報取得関数|ユーザ情報取得関数}〕…)
-
BETWEEN述語で次に示す形式の場合は,OR条件中の条件をOR条件の外側に抜き出します。
{列指定|列指定[ANY〔(識別番号)〕]} 〔NOT〕 BETWEEN {定数|日時情報取得関数|ユーザ情報取得関数} AND {定数|日時情報取得関数|ユーザ情報取得関数}
-
次に示す場合は等価変換されません。
-
NOT条件中に指定されたOR条件の場合(「(2) 等価変換されない例」の「(b) 例2」を参照)
-
AND条件に指定されたOR条件の場合(「(2) 等価変換されない例」の「(c) 例3」を参照)
-