Ví dụ:
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;
Nếu bạn chạy tập lệnh trước đó trong SSMS (nhấn Ctrl+M
-> Kế hoạch thực thi thực tế) thì bạn sẽ nhận được kế hoạch thực thi này cho truy vấn cuối cùng:
Trong trường hợp này, CTE được thực thi một lần cho crt
bí danh và năm (!) lần cho prev
bí danh, một lần cho mỗi hàng từ crt
.
Vì vậy, câu trả lời cho câu hỏi này
là both
:một lần cho mỗi truy vấn (crt
) và một lần mỗi hàng (prev
:một lần cho mỗi từ crt
).
Để tối ưu hóa truy vấn này, ngay từ đầu, 1) Bạn có thể cố gắng lưu trữ kết quả từ CTE (MyCTE
hoặc Query
) thành một biến bảng hoặc một bảng tạm thời
2) Xác định khóa chính của bảng này như là (các) cột tham gia,
3) Viết lại truy vấn cuối cùng để sử dụng biến bảng này hoặc bảng tạm thời.
Tất nhiên, bạn có thể cố gắng viết lại truy vấn cuối cùng mà không có sự kết hợp tự này giữa CTE.