Common Table Expression を使用してメニューの階層パスを作成するストアド プロシージャがあります (親メニュー -> サブ メニュー -> サブ サブ メニュー -> ... のようなものを表示できます)。
それは私がそれを使いたいと思っているものにはうまく機能します.問題は、再帰CTEから取得した情報を本当に必要な情報に入れるときに発生します. データから CTE への内部結合を行い、階層パスを取得します。約 300 行を返す場合、ストアド プロシージャは平均 15 ~ 20 秒かかります。
CTE からの結果を一時テーブルに挿入し、それに基づいて結合を実行すると、手順に 1 秒もかかりません。
CTE だけを使用して参加するのになぜそんなに時間がかかるのか、または何らかの方法で CTE を誤用しているのではないかと思っていました。
**編集これは本質的にストアドプロシージャです
With Hierarchical_Path (Menu_ID, Parent_ID, Path)
As
(
Select
EM.Menu_Id, Parent_ID,
Convert(varchar(max),
EM.Description) as Path
From
Menu EM
Where
--EM.Topic_No is null
EM.Parent_ID = 0 and EM.Disabled = 0
Union All
Select
EM.Menu_ID,
EM.Parent_ID,
Convert(Varchar(max),E.Path + ' -> ' + EM.Description) as Path
From
Menu EM
Inner Join
Hierarchical_Path E
On
EM.Parent_ID = E.Menu_ID
)
SELECT distinct
EM.Description
,EMS.Path
FROM
dbo.Menu em
INNER JOIN
Hierarchical_Path EMS
ON
EMS.Menu_ID = em.Menu_Id
2 more INNER JOINs
2 Left Joins
WHERE Clause
このように (CTE に参加して) クエリを実行すると、パフォーマンスは約 20 秒です。
CTE の結果を一時テーブルに挿入して結合すると、パフォーマンスは瞬時に向上します。
クエリをもう少し分解すると、where 句に引っかかっているようです。私の質問は、CTEがいつ実行され、メモリに保存されるのかという点にあると思いますか? 一度呼び出されてメモリに残るという前提で実行していましたが、状況によっては複数回呼び出される可能性がありますか?