Đây hoàn toàn không phải là một câu trả lời chính tắc nhưng tôi nhận thấy rằng đối với các kế hoạch truy vấn vòng lặp lồng nhau được hiển thị trong SQL Fiddle, có thể áp dụng kế hoạch từ Truy vấn 2 đến Truy vấn 1 với việc sử dụng USE PLAN
gợi ý nhưng việc thử thao tác ngược lại thất bại với
Bộ xử lý truy vấn không thể tạo kế hoạch truy vấn vì gợi ý USE PLAN chứa gói không thể xác minh là hợp pháp cho truy vấn. Xóa hoặc thay thế gợi ý SỬ DỤNG KẾ HOẠCH. Để có khả năng buộc kế hoạch thành công tốt nhất, hãy xác minh rằng gói được cung cấp trong gợi ý USE PLAN là một máy chủ được tạo tự động bởi SQL Server cho cùng một truy vấn.
Vô hiệu hóa quy tắc chuyển đổi tối ưu hóa cũng ReorderLOJN
ngăn cản gợi ý kế hoạch thành công trước đó thành công.
Thử nghiệm với số lượng lớn hơn các chương trình dữ liệu SQL Server là chắc chắn có khả năng chuyển (A LOJ B) LOJ C
đến A LOJ (B LOJ C)
một cách tự nhiên cũng nhưng tôi không thấy bất kỳ bằng chứng cho thấy điều ngược lại là đúng.
Một trường hợp rất dễ xảy ra khi truy vấn đầu tiên thực hiện tốt hơn truy vấn thứ hai là
DROP TABLE MyGrandChild , MyChild, MyParent
CREATE TABLE MyParent
(Id int)
CREATE TABLE MyChild
(Id int PRIMARY KEY
,ParentId int,
Filler char(8000) NULL)
CREATE TABLE MyGrandChild
(Id int
,ParentId int)
INSERT INTO MyChild
(Id, ParentId)
SELECT TOP (100000) ROW_NUMBER() OVER (ORDER BY @@SPID),
ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM master..spt_values v1, master..spt_values
INSERT INTO MyGrandChild
(Id, ParentId)
OUTPUT INSERTED.Id INTO MyParent
SELECT TOP (3000) Id, Id AS ParentId
FROM MyChild
ORDER BY Id
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
SELECT gc.Id AS gcId,
gc.ParentId AS gcpId,
c.Id AS cId,
c.ParentId AS cpId,
p.Id AS pId
FROM MyGrandChild AS gc
LEFT OUTER JOIN MyChild AS c
ON c.[Id] = gc.[ParentId]
LEFT OUTER JOIN MyParent AS p
ON p.[Id] = c.[ParentId]
SELECT gc.Id AS gcId,
gc.ParentId AS gcpId,
c.Id AS cId,
c.ParentId AS cpId,
p.Id AS pId
FROM MyGrandChild AS gc
LEFT OUTER JOIN( MyChild AS c
LEFT OUTER JOIN MyParent AS p
ON p.[Id] = c.[ParentId])
ON c.[Id] = gc.[ParentId]
Mà đưa ra kế hoạch

Đối với tôi Truy vấn 1 có thời gian trôi qua là 108 ms so với 1.163 ms cho Truy vấn 2.
Truy vấn 1
Table 'Worktable'. Scan count 0, logical reads 0
Table 'MyChild'. Scan count 0, logical reads 9196
Table 'MyGrandChild'. Scan count 1, logical reads 7
Table 'MyParent'. Scan count 1, logical reads 5
Truy vấn 2
Table 'MyParent'. Scan count 1, logical reads 15000
Table 'MyChild'. Scan count 0, logical reads 9000
Table 'MyGrandChild'. Scan count 1, logical reads 7
Vì vậy, có thể tạm thời giả định rằng cú pháp đầu tiên ("không được kiểm tra") có khả năng có lợi vì nó cho phép các đơn đặt hàng tham gia tiềm năng hơn được xem xét nhưng tôi đã không thực hiện đủ thử nghiệm để có thể tin tưởng vào quy tắc chung này.
Hoàn toàn có thể đưa ra các ví dụ truy cập trong đó Truy vấn 2 hoạt động tốt hơn. Hãy thử cả hai và nhìn vào các kế hoạch thực hiện.