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.