例:
SET NOCOUNT ON;
SET IMPLICIT_TRANSACTIONS ON;
CREATE TABLE MyTable (MyID INT PRIMARY KEY);
GO
INSERT MyTable (MyID)
VALUES (11), (22), (33), (44), (55);
PRINT 'Test MyCTE:';
WITH MyCTE
AS (
SELECT *, ROW_NUMBER()OVER(ORDER BY MyID) AS RowNum
FROM MyTable
)
SELECT *
FROM MyCTE crt
LEFT JOIN MyCTE prev ON crt.RowNum=prev.RowNum+1;
ROLLBACK;
SSMS で以前のスクリプトを実行した場合 (Ctrl+M
を押します) -> 実際の実行計画) を実行すると、最後のクエリの実行計画が取得されます。
この場合、CTE は crt
に対して 1 回実行されます。 prev
のエイリアスと 5 回 (!) 回 エイリアス、crt
のすべての行に 1 回 .
では、この質問の答えは
both
です :クエリごとに 1 回 (crt
) および行ごとに 1 回 (prev
:crt
から毎回 1 回 ).
このクエリを最適化するには、まず、1) CTE (MyCTE
) からの結果を保存してみてください。 または Query
) テーブル変数または一時テーブルに
2) このテーブルの主キーを結合列として定義します。
3) このテーブル変数または一時テーブルを使用するように最終クエリを書き直します。
もちろん、この CTE 間の自己結合なしで最終的なクエリを書き直すこともできます。