msdnから:
派生テーブルとは異なり、CTEは自己参照することができ、同じクエリで複数回参照できます。
私はCTEをかなり頻繁に使用していますが、CTEを使用する利点について深く考えたことはありません。
同じクエリでCTEを複数回参照する場合:
- パフォーマンス上の利点はありますか?
- 自己結合を実行している場合、SQL Serverはターゲットテーブルを2回スキャンしますか?
msdnから:
派生テーブルとは異なり、CTEは自己参照することができ、同じクエリで複数回参照できます。
私はCTEをかなり頻繁に使用していますが、CTEを使用する利点について深く考えたことはありません。
同じクエリでCTEを複数回参照する場合:
回答:
原則として、CTEはパフォーマンスを決して改善しません。
CTEは本質的に使い捨てのビューです。追加の統計情報やインデックスなどは保存されていません。サブクエリの短縮形として機能します。
私の意見では、それらは簡単に使い古される可能性があります(私の仕事ではコードに多くの使いすぎが見られます)。 いくつかの良い答えはここにありますが、何かを複数回参照する必要がある場合、または数十万行を超える場合は、#temp
代わりにテーブルに入れてインデックスを作成します。
CTE
、最初のクエリの後に結果が破棄されるため、a は不適切な選択です。
再帰以外にCTEが非常に役立つと思う場所の1つは、複雑なレポートクエリを作成するときです。一連のCTEを使用して必要なデータのチャンクを取得し、最終選択で結合します。多数の派生テーブルや20の結合で同じことを行うよりも保守が容易であることがわかります。また、すべての異なる結合。簡単な例を挙げましょう。
;WITH Conferences (Conference_id)
AS
(select m.Conference_id
FROM mydb.dbo.Conference m
WHERE client_id = 10
and Conference_id in
(select Conference_id from mydb.dbo.Expense
where amount <>0
and amount is not null)
)
--select * from Conferences
,MealEaters(NumberMealEaters, Conference_id, AttendeeType)
AS
(Select count(*) as NumberMealEaters, m.Conference_id, AttendeeType
from mydb.dbo.attendance ma
join Conferences m on m.Conference_id = ma.Conference_id
where (ma.meals_consumed>0 or meals_consumed is null)and attended = 1
group by m.Conference_id)
--select * from MealEaters
,Expenses (Conference_id,expense_date, expenseDescription, RecordIdentifier,amount)
AS
(select Conference_id,max(expense_date) as Expense_date, expenseDescription, RecordIdentifier,sum(amount) as amount
FROM
(SELECT Conference_id,expense_date, amount, RecordIdentifier
FROM mydb.dbo.Expense
WHERE amount <> 0
and Conference_id IN
(SELECT Conference_id
FROM mydb.dbo.Conferences )
group by Conference_id, RecordIdentifier) a
)
--select * from Expenses
Select m.Conference_id,me.NumberMealEaters, me.AttendeeType, e.expense_date, e.RecordIdentifier,amount
from Conferences m
join mealeaters me on m.Conference_id = me.Conference_id
join expenses e on e.Conference_id = m.Conference_id
したがって、必要な情報のさまざまなチャンクを分離することにより、各部分を個別にチェックできます(コメントアウトされた選択を使用して、各コメントを個別にアンコメントし、その選択範囲までのみ実行します)および費用を変更する必要がある場合計算(この例)では、それらがすべて1つの大規模なクエリに混在している場合よりも簡単に見つけることができます。もちろん、これを使用する実際のレポートクエリは、一般に例よりもはるかに複雑です。