SELECT sans FROM <table> mais avec APPLY / JOIN

J'écris une procédure et j'ai besoin de quelques identifiants de key étrangère pour d'autres opérations

table md_machines

 +----+-------+ | id | name | +----+-------+ | 1 | c432 | | 2 | c431 | | n | ... | +----+-------+ 

ma requête dans ma procédure:

 SELECT TOP 1 @m1 = m1.id, @m2 = m2.id, @m3 = m3.id, @m4 = m4.id FROM md_machines OUTER APPLY(SELECT TOP 1 id FROM md_machines WHERE name = @p1) m1 OUTER APPLY(SELECT TOP 1 id FROM md_machines WHERE name = @p2) m2 OUTER APPLY(SELECT TOP 1 id FROM md_machines WHERE name = @p3) m3 OUTER APPLY(SELECT TOP 1 id FROM md_machines WHERE name = @p4) m4 

Tout fonctionne bien, mais md_machines a plus de 300k lignes. Lorsque je remplace FROM md_machines avec une table vide, cette requête est environ 10% plus rapide.
Comment puis-je éviter FROM md_machines ? Ce n'est pas nécessaire pour moi.

select-les une fois

 SELECT name, min(id) FROM md_machines WHERE (name = @p1 or name = @p2 or name = @p3 or name = @p4) group by name 

puis utilisez la requête ci-dessus avec WITH

 WITH sub (name, id) AS ( the suquery ) SELECT TOP 1 @m1 = m1.id, @m2 = m2.id, @m3 = m3.id, @m4 = m4.id FROM (SELECT TOP 1 id FROM sub WHERE name = @p1) m1, (SELECT TOP 1 id FROM sub WHERE name = @p2) m2, (SELECT TOP 1 id FROM sub WHERE name = @p3) m3, (SELECT TOP 1 id FROM sub WHERE name = @p4) m4 

BTW: serait bien d'avoir un index sur la colonne de name

MISE À JOUR: Je pense que celui-ci fonctionnera aussi bien

 SELECT TOP 1 @m1 = m1.id, @m2 = m2.id, @m3 = m3.id, @m4 = m4.id FROM (SELECT TOP 1 id FROM md_machines WHERE name = @p1) m1, (SELECT TOP 1 id FROM md_machines WHERE name = @p2) m2, (SELECT TOP 1 id FROM md_machines WHERE name = @p3) m3, (SELECT TOP 1 id FROM md_machines WHERE name = @p4) m4 

Utilisez une affectation de variable simple:

 SET @m1 = (SELECT TOP 1 id FROM md_machines WHERE name = @p1); SET @m2 = (SELECT TOP 1 id FROM md_machines WHERE name = @p2); SET @m3 = (SELECT TOP 1 id FROM md_machines WHERE name = @p3); SET @m4 = (SELECT TOP 1 id FROM md_machines WHERE name = @p4); 

TOP 1 sans ORDER BY explicite n'est pas stable.