La documentation est un peu trompeuse. Le DMV est une vue non matérialisée et n'a pas de clé primaire en tant que telle. Les définitions sous-jacentes sont un peu complexes mais une définition simplifiée de sys.query_store_planest:
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;
En outre, sys.plan_persist_plan_mergedest également une vue, bien qu'il soit nécessaire de se connecter via la connexion administrateur dédiée pour voir sa définition. Encore une fois, simplifié:
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;
Les index sur sys.plan_persist_plansont:
╔════════════════════════╦════════════════════════ ══════════════╦═════════════╗
║ nom_index ║ description_index ║ clés_index ║
╠════════════════════════╬════════════════════════ ══════════════╬═════════════╣
║ plan_persist_plan_cidx ║ clusterisé, unique situé sur PRIMARY ║ plan_id ║
║ plan_persist_plan_idx1 ║ non cluster situé sur PRIMARY ║ query_id (-) ║
╚════════════════════════╩════════════════════════ ══════════════╩═════════════╝
Il plan_idest donc contraint d'être unique sur sys.plan_persist_plan.
Maintenant, sys.plan_persist_plan_in_memoryest une fonction de table en continu, présentant une vue tabulaire des données uniquement conservées dans les structures de mémoire interne. En tant que tel, il n'a pas de contraintes uniques.
Au fond, la requête en cours d'exécution est donc équivalente à:
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;
... qui ne produit pas d'élimination des jointures:

Pour aller directement au cœur du problème, le problème est la requête interne:
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;
... il est clair que la jointure gauche peut entraîner la @t2duplication des lignes car elle @t3n'a pas de contrainte d'unicité plan_id. Par conséquent, la jointure ne peut pas être éliminée:

Pour contourner ce problème, nous pouvons explicitement dire à l'optimiseur que nous n'avons pas besoin de plan_idvaleurs en double :
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;
La jointure externe à @t3peut maintenant être éliminée:

Appliquer cela à la vraie requête:
SELECT DISTINCT
T.plan_id
FROM #tears AS T
LEFT JOIN sys.query_store_plan AS QSP
ON QSP.plan_id = T.plan_id;
De même, nous pourrions ajouter GROUP BY T.plan_idau lieu de DISTINCT. Quoi qu'il en soit, l'optimiseur peut désormais raisonner correctement sur l' plan_idattribut tout au long des vues imbriquées et éliminer les deux jointures externes comme vous le souhaitez:

Notez que rendre plan_idunique dans la table temporaire ne serait pas suffisant pour obtenir l'élimination des jointures, car cela n'empêcherait pas des résultats incorrects. Nous devons explicitement rejeter les plan_idvaleurs en double du résultat final pour permettre à l'optimiseur de travailler sa magie ici.