Các tài liệu là một chút sai lệch. DMV là chế độ xem không cụ thể hóa và không có khóa chính như vậy. Các định nghĩa cơ bản là một chút phức tạp nhưng một định nghĩa đơn giản sys.query_store_plan
là:
CREATE VIEW sys.query_store_plan AS
SELECT
PPM.plan_id
-- various other attributes
FROM sys.plan_persist_plan_merged AS PPM
LEFT JOIN sys.syspalvalues AS P
ON P.class = 'PFT'
AND P.[value] = plan_forcing_type;
Hơn nữa, sys.plan_persist_plan_merged
cũng là một khung nhìn, mặc dù người ta cần kết nối thông qua Kết nối quản trị viên chuyên dụng để xem định nghĩa của nó. Một lần nữa, đơn giản hóa:
CREATE VIEW sys.plan_persist_plan_merged AS
SELECT
P.plan_id as plan_id,
-- various other attributes
FROM sys.plan_persist_plan P
-- NOTE - in order to prevent potential deadlock
-- between QDS_STATEMENT_STABILITY LOCK and index locks
WITH (NOLOCK)
LEFT JOIN sys.plan_persist_plan_in_memory PM
ON P.plan_id = PM.plan_id;
Các chỉ số trên sys.plan_persist_plan
là:
╔════════════════════════╦════════════════════════ ══════════════╦═════════════╗
║ index_name ║ index_description ║ index_keys
╠════════════════════════╬════════════════════════ ══════════════╬═════════════╣
║ plan_persist_plan_cidx ║ cụm, duy nhất nằm trên PRIMARY plan_id
║ plan_persist_plan_idx1 không được đặt trên PRIMARY ║ query_id (-)
╚════════════════════════╩════════════════════════ ══════════════╩═════════════╝
Vì vậy, plan_id
bị hạn chế là duy nhất trên sys.plan_persist_plan
.
Bây giờ, sys.plan_persist_plan_in_memory
là một hàm có giá trị bảng phát trực tuyến, hiển thị dạng xem bảng của dữ liệu chỉ được giữ trong các cấu trúc bộ nhớ trong. Như vậy, nó không có bất kỳ ràng buộc duy nhất.
Do đó, truy vấn đang được thực hiện tương đương với:
DECLARE @t1 table (plan_id integer NOT NULL);
DECLARE @t2 table (plan_id integer NOT NULL UNIQUE CLUSTERED);
DECLARE @t3 table (plan_id integer NULL);
SELECT
T1.plan_id
FROM @t1 AS T1
LEFT JOIN
(
SELECT
T2.plan_id
FROM @t2 AS T2
LEFT JOIN @t3 AS T3
ON T3.plan_id = T2.plan_id
) AS Q1
ON Q1.plan_id = T1.plan_id;
... mà không tạo ra sự loại bỏ tham gia:
Đi thẳng vào cốt lõi của vấn đề, vấn đề là truy vấn bên trong:
DECLARE @t2 table (plan_id integer NOT NULL UNIQUE CLUSTERED);
DECLARE @t3 table (plan_id integer NULL);
SELECT
T2.plan_id
FROM @t2 AS T2
LEFT JOIN @t3 AS T3
ON T3.plan_id = T2.plan_id;
... rõ ràng việc nối bên trái có thể khiến các hàng không @t2
bị trùng lặp vì @t3
không có ràng buộc duy nhất nào plan_id
. Do đó, việc tham gia không thể được loại bỏ:
Để khắc phục điều này, chúng tôi có thể nói rõ ràng với trình tối ưu hóa rằng chúng tôi không yêu cầu bất kỳ plan_id
giá trị trùng lặp nào :
DECLARE @t2 table (plan_id integer NOT NULL UNIQUE CLUSTERED);
DECLARE @t3 table (plan_id integer NULL);
SELECT DISTINCT
T2.plan_id
FROM @t2 AS T2
LEFT JOIN @t3 AS T3
ON T3.plan_id = T2.plan_id;
Tham gia bên ngoài để @t3
bây giờ có thể được loại bỏ:
Áp dụng điều đó cho truy vấn thực sự:
SELECT DISTINCT
T.plan_id
FROM #tears AS T
LEFT JOIN sys.query_store_plan AS QSP
ON QSP.plan_id = T.plan_id;
Tương tự, chúng ta có thể thêm GROUP BY T.plan_id
thay vì DISTINCT
. Dù sao, trình tối ưu hóa giờ đây có thể lý giải chính xác về plan_id
thuộc tính cho đến hết các khung nhìn lồng nhau và loại bỏ cả hai phép nối ngoài như mong muốn:
Lưu ý rằng làm cho plan_id
duy nhất trong bảng tạm thời sẽ không đủ để có được loại bỏ tham gia, vì nó sẽ không loại trừ kết quả không chính xác. Chúng ta phải từ chối một cách rõ ràng plan_id
các giá trị trùng lặp từ kết quả cuối cùng để cho phép trình tối ưu hóa thực hiện phép thuật của nó ở đây.