2016-12-23 7 views
1
SELECT in_ev.type, pl.name, in_ev.year 
FROM places pl INNER JOIN (SELECT e.type, e.place_id, e.year 
          FROM events e)in_ev ON in_ev.place_id=pl.place_id 
WHERE EXISTS (SELECT 1 FROM in_ev sub_ev WHERE sub_ev.year=1994) 

は、私がどのように処理されるかインライン・ビューを理解しようとしていると、なぜ我々は、where句のサブクエリで「ソーステーブル」としてそれらを使用することはできません。この問合せを実行しようとすると、ORA-00942:表またはビューは存在しません。インライン・ビューの制限

上記のスニペットは説明のためのものです。

通常のテーブルとインラインビューの間の記憶と処理の正確な違いは何ですか?

答えて

2

where句のサブクエリはインラインビューを表示できません。これはわかっていると思います。それは本当に範囲の問題です。ストレージがなく、メモリ内でどのように管理され、処理されるかは、オプティマイザに多少なりともあります。インラインビューが評価される前にサブクエリが論理的に評価されるかもしれません。

問合せが実際に実行される前にパーサーがORA-00942をスローしているため、インライン・ビューの処理方法は疑問点です。

あなたは代わりにサブクエリファクタリング使用することができます、このような不自然な例と奇妙に見える

WITH in_ev AS (
    SELECT e.type, e.place_id, e.year 
    FROM events e 
) 
SELECT in_ev.type, pl.name, in_ev.year 
FROM places pl INNER JOIN in_ev ON in_ev.place_id=pl.place_id 
WHERE EXISTS (SELECT 1 FROM in_ev sub_ev WHERE sub_ev.year=1994) 

をしますが、それは問題の実例だとacknowleged。 where節のサブクエリで、CTEを参照してください。これはパーサの範囲に含まれています。

@mathguyがコメントで述べたように、オプティマイザは依然としてCTEをサブクエリとして扱いますが、通常はあなたが気にする必要はありません。特に、あなたが得たエラーを回避しようとしている場合は特にそうです。

+1

アレックスの説明に追加し、さらに評価とストレージに関する質問に答えてください:オプティマイザがファクタリングされたサブクエリ(WITH句の「ビュー」)を見ているときは、自由に2つのオプションを考えて、より効率的です。 1つはインラインビューとして扱うことです(FROMとWHERE節の両方でインプレース評価)。または、一時的なグローバルテーブルとして扱うことができます。一度だけ計算して保存し、残りのクエリで使用されるストアドテーブルを使用する場合と同じように使用できます。 CBOがどの選択肢を選択するかは、いくつかの点で異なります。 – mathguy

関連する問題