Partage
  • Partager sur Facebook
  • Partager sur Twitter

[SQL SERVER] Optimisation sous requête

    18 janvier 2019 à 10:33:54

    Hello !

    Je suis sous SQL Server, je me posais une petite question concernant les sous-requêtes. Je pense savoir la réponse mais j'aimerais en être sûr.

    Imaginons une procédure simple ou non du type

    SELECT maTable.champ1, maTable.champ2, COUNT(maTable.champ3)
    FROM maTable
    WHERE maTable.champ4 = 'valeur'
    AND maTable.champ5 = (SELECT TOP 1 maTable2.champ1 FROM maTable2)
    GROUP BY maTable.champ1, maTable.champ2
    ORDER BY maTable.champ1

    Ma question est la suivante, la sous-requête est-elle exécutée une fois ou à chaque ligne pour vérifier l'égalité avec maTable.champ5 ? Dans le 2e cas, il serait peut-être mieux d'utiliser une variable de cette manière avant le select et de remplacer la requête imbriquée par la variable ?

    DECLARE @champ5 INT
    SET @champ5 = (SELECT TOP 1 maTable2.champ1 FROM maTable2)

    puis

    AND maTable.champ5 = @champ5


    Tant que j'y suis, deuxième situation, c'est sûrement la même chose dans le cas où le select imbriqué renvoie une table (je ne vais pas réécrire la requête, mais globalement on remplace le = par IN dans le WHERE et on déclare à la place une table d'INT dans le cas où l'on veut utiliser une table temporaire...). Qu'en est-il des performances dans ces deux situations, en fonction de l'utilisation d'une variable ou d'une requête imbriquée ? Le moteur est-il assez futé pour ne pas le recalculer à chaque fois ? Pour la seconde situation avec la table temporaire, il me semble avoir lu quelque part que les IN ne sont pas terribles en terme de perf, vous avez des infos ?

    Merci d'avance et très bonne journée :)



    -
    Edité par Grillaume 18 janvier 2019 à 10:42:15

    • Partager sur Facebook
    • Partager sur Twitter
      18 janvier 2019 à 11:35:30

      Hello,

      Pour la 1ère question, non ce n'est joué qu'une seule fois. Tu n'es pas pas obligé de faire un DECLARE.

      Après, on peut éventuellement trouver ça plus propre de faire un DECLARE pour ne pas avoir de sous-requête. Question de gout je dirais.

      Dans ton 2ème cas, alors plutôt que de faire un IN (qui fonctionnerait), autant faire un jointure, c'est plus propre et un poils plus opti :

      SELECT t1.champ1, t1.champ2, COUNT(t1.champ3)
      FROM maTable t1
      INNER JOIN maTable2 t2
      	ON t2.champ1 = t1.champ5
      WHERE maTable.champ4 = 'valeur'
      GROUP BY t1.champ1, t1.champ2
      ORDER BY t1.champ1



      • Partager sur Facebook
      • Partager sur Twitter
        22 janvier 2019 à 9:26:58

        Merci pour ta réponse Tiffado.

        En effet, dans le 2nd cas c'est un gros poil plus optimisé: après un paquet de test, sur une de mes procédures stockées j'ai un temps d’exécution moyen de 940ms avec un IN, contre 210ms juste en modifiant la requête pour faire une jointure...

        • Partager sur Facebook
        • Partager sur Twitter

        [SQL SERVER] Optimisation sous requête

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown