依存します。オプティマイザはサブクエリのコストを評価します。コストが十分に高い場合(複雑さやサイズのために)、Oracleはグローバル一時表としてマテリアライズし、ディスクに書き出します。そうすることで明確なメリットがある場合に限り、CTEを使用してください。
メリットの1つは、メインクエリでCTEの結果を複数回再利用できることです。だからあなたの例を拡張:
with test_cte as(
select *
from table1
where conditions1
)
select *
from table2
inner join test_cte
on conditions2
where table1.whatever not in (select whatever
from test_cte
where conditions3)
ここでは、一度table1
を照会しているが、2倍のレコードを使用。
with test_cte as(
select *
from table1
where conditions1
)
, next_cte as (
select t1.*
, t23.*
from test_cte t1
join table23 t23
on t1.id = t23.id)
select *
from next_cte
これはチャンクを理解することが容易に複雑なクエリを壊すのに有用であることができます。
のCTEのもう一つの利点は、我々は彼らをチェーンことができるということです。ただし、このルートに着手する前にオプティマイザよりも明確になっていることを確認することは重要です。
WITH句のもう1つの用途は、再帰的なクエリの作成です。 11gR2以降、Oracleの階層問合せ構文を使用せずに親子関係をナビゲートできるようになりました。 Find out more。
with cte (id, parent_id, lvl) as
(select id, p_id, 0 as lvl
from t23
where p_id is null
union all
select t23.id, t23.p_id, cte.lvl + 1
from cte
join t23
on cte.id = t23.p_id)
select *
from cte
order by lvl, id
/
出典
2017-02-17 11:40:41
APC
「テーブル」を1回使用するとすぐに消える一時テーブルと考えてください。 – Snowlockk
@Snowlockk - あなたはどこでそれを考え出しましたか? CTEは、テンポラリ・テーブルまたはインライン・ビュー(サブクエリ)のいずれかとして使用でき、オプティマイザはどちらを選択するかを決定します。 ** CTEは一度**使用されるとすぐに消えません。 – mathguy
しばらくしてからもう一度電話をかけてください。 – Snowlockk