WITH
句はサブクエリファクタリング用であり、一般的なテーブル式またはCTEとも呼ばれます。
WITH query_name句を使用すると、サブクエリブロックに名前を割り当てることができます。次に、query_nameを指定することにより、クエリ内の複数の場所でサブクエリブロックを参照できます。 Oracle Databaseは、クエリ名をインライン・ビューまたは一時表として扱うことにより、クエリを最適化します。
2番目の例では、temp_table
と呼んでいます。 はインラインビューであり、一時的なテーブルではありません。
多くの場合、どちらを使用するかの選択は好みのスタイルに依存し、CTEは、特に複数レベルのサブクエリでコードを読みやすくすることができます(意見はもちろん異なります)。 CTE /インラインビューを一度だけ参照すると、パフォーマンスに違いは見られない可能性があり、オプティマイザーは同じ計画になる可能性があります。
ただし、ユニオンなど、複数の場所で同じサブクエリを使用する必要がある場合は、特に便利です。インラインビューをCTEにプルアウトして、コードが繰り返されないようにすることができます。これにより、オプティマイザーは、それが有益であると判断した場合にそれを具体化できます。
たとえば、この不自然な例:
select curr from (
select curr from tableone t1
left join tabletwo t2 on (t1.empid = t2.empid)
) temp_table
where curr >= 0
union all
select -1 * curr from (
select curr from tableone t1
left join tabletwo t2 on (t1.empid = t2.empid)
) temp_table
where curr < 0
次のようにリファクタリングできます:
with temp_table as (
select curr from tableone t1
left join tabletwo t2 on (t1.empid = t2.empid)
)
select curr from temp_table
where curr >= 0
union all
select -1 * curr from temp_table
where curr < 0
サブクエリを繰り返す必要がなくなりました。繰り返されるコードが複雑になるほど、CTEを使用することはメンテナンスの観点からより有益です。また、サブクエリのコストが高いほど、パフォーマンスが向上します。 CTEの使用から見てください。ただし、オプティマイザーは通常、とにかく何をしているかを理解するのにかなり優れています。