ネストされた副問合せのネスト解除

副問合せという用語は、WHERE句およびHAVING句に表示される副問合せブロックを指します。FROM句に表示される副問合せは、ビューまたは導出表と呼ばれます。

WHERE句副問合せは、SINGLE-ROW EXISTSNOT EXISTSANYまたはALLのいずれかのタイプに属します。単一行副問合せは最大1行を返す必要がありますが、他のタイプの副問合せではゼロ以上の行を返すことができます。

ANYおよびALL副問合せは、リレーショナル比較演算子(=、>、>=、<、<=および<>)とともに使用されます。

SQLでは、集合演算子INは=ANYの短縮形として使用され、集合演算子NOT IN は<>ALLの短縮形として使用されます。

例: 相関EXISTS副問合せ

この例の副問合せは相関しています。列C.cust_idが、副問合せで定義されていない表customersから取得されるためです。

SELECT C.cust_last_name, C.country_id
        FROM customers C
        WHERE EXISTS (SELECT 1
              FROM sales S
              WHERE S.quantity_sold > 1000 and
                    S.cust_id = C.cust_id);

ネストされた副問合せは、SELECTなどの親文のWHERE句およびHAVING句に表示される副問合せです。ネストされた副問合せを持つ文を評価する場合、Oracle Databaseは、副問合せ部分を複数回評価する必要があり、より効果的なアクセス・パスまたは結合を見逃してしまう可能性があります。

副問合せのネスト解除は、副問合せを外部問合せの結合に変換し、オプティマイザがアクセス・パス、結合方法および結合順序の選択時に副問合せ表を考慮できる最適化です。いずれかのネストを解除すると、副問合せが外部問合せブロックの本体にマージされるか、インライン・ビューになります。

副問合せがネスト解除されると、その副問合せはそれを含む文にマージされ、オプティマイザは、アクセス・パスと結合を評価するときに、副問合せと文を一緒に考慮できます。オプティマイザは、ほぼすべての副問合せをネスト解除できますが、いくつか例外があります。これらの例外としては、階層副問合せ、およびROWNUM疑似列、集合演算子の1つ、ネストした集計ファンクション、副問合せの直接的な外部問合せブロックではない問合せブロックへの相関参照を含む副問合せなどがあります。

制約がない場合、オプティマイザは、次のネストされた副問合せを自動的にネスト解除します(ただし、ネスト解除しない場合もあります)。

  • 相関関係のないIN副問合せ

  • INおよびEXISTS相関副問合せ(集計ファンクションまたはGROUP BY句を含まない場合)

ネスト解除された拡張副問合せを行うには、次のタイプの副問合せをネスト解除するようにオプティマイザに指示します。

  • 副問合せにHASH_AJまたはMERGE_AJヒントを指定して、NOT IN副問合せをネスト解除します。

  • 副問合せにUNNESTヒントを指定して、その他の副問合せをネスト解除します。

    関連項目:

    ヒントの詳細は、「ヒント」を参照してください。

例: 相関関係のないANY副問合せ

SELECT C.cust_last_name, C.country_id
        FROM customers C        
        WHERE C.cust_id =ANY (SELECT S.cust_id
                      FROM sales S
                      WHERE S.quantity_sold > 1000);

例: NOT EXISTS副問合せ


SELECT C.cust_last_name, C.country_id
FROM customers C
WHERE NOT EXISTS (SELECT 1
                  FROM sales S, products P
                  WHERE P.prod_id = S.prod_id and
                        P.prod_min_price > 90 and
                        S.cust_id = C.cust_id);