IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MS SQL Server Discussion :

GROUP BY multiples (Performance)


Sujet :

MS SQL Server

  1. #1
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut GROUP BY multiples (Performance)
    Bonjour à tous,

    J'ai une question que je me pose souvent. J'aimerais déterminer de façon général, laquelle des deux requêtes suivante est la plus performante et la bonne façon de faire.

    Toute d'abord, prenons la table suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    DECLARE @TbEmployee TABLE(EmployeeID INT, EmpSubordinateID INT, EmpFirstName VARCHAR(40), EmpLastName VARCHAR(40), EmpPhoneNumber VARCHAR(40) )
    INSERT INTO @TbEmployee
    SELECT 1, NULL, 'e1', 'e1', '888-888-8888'
    UNION ALL
    SELECT 2, NULL, 'e2', 'e2', '888-888-8888'
    UNION ALL
    SELECT 3, 1, 'e3', 'e3', '888-888-8888'
    UNION ALL
    SELECT 4, 3, 'e4', 'e4', '888-888-8888'
    UNION ALL
    SELECT 5, 4, 'e5', 'e5', '888-888-8888'
    UNION ALL
    SELECT 6, 5, 'e6', 'e6', '888-888-8888'
    Cette table contient des employés. Chaque employé est susceptible d'être le patron d'un autre. Enfin bref, imagons maintenant que je désire récupérer la liste de tous les employés ainsi que le nombre de subordinné (immédiat) étant associé à chacun d'eux.

    Voilà la méthode #1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    SELECT TbEmployee.EmployeeID, 
           TbEmployee.EmpSubordinateID, 
           TbEmployee.EmpFirstName, 
           TbEmployee.EmpLastName, 
           TbEmployee.EmpPhoneNumber,
           COUNT(TbSubordinate.EmployeeID)
    FROM @TbEmployee AS TbEmployee
         LEFT JOIN @TbEmployee AS TbSubordinate
               ON TbEmployee.EmployeeID = TbSubordinate.EmpSubordinateID
    GROUP BY TbEmployee.EmployeeID, 
             TbEmployee.EmpSubordinateID, 
             TbEmployee.EmpFirstName, 
             TbEmployee.EmpLastName, 
             TbEmployee.EmpPhoneNumber
    Ici, j'utilise un GROUP BY qui d'après mes connaissance semble couteux vu le nombre d'argument qu'il possède.

    Maintenant, voyons la méthode #2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    SELECT TableEmp.EmpFirstName, 
           TableEmp.EmpLastName, 
           TableEmp.EmpPhoneNumber,
           TableTotal.NombreDeSub
    FROM
          (
              SELECT TbEmployee.EmployeeID, 
                     TbEmployee.EmpSubordinateID, 
                     COUNT(TbSubordinate.EmployeeID) AS NombreDeSub
              FROM @TbEmployee AS TbEmployee
                   LEFT JOIN @TbEmployee AS TbSubordinate
                       ON TbEmployee.EmployeeID = TbSubordinate.EmpSubordinateID
              GROUP BY TbEmployee.EmployeeID, 
                       TbEmployee.EmpSubordinateID 
           ) 
           AS TableTotal
                INNER JOIN @TbEmployee AS TableEmp
                      ON TableEmp.EmployeeID = TableTotal.EmployeeID
    Cette dernière méthode commence par regrouper les données en fonction du ID de l'employé ensuite, elle joint le tout à la table Employee afin de récupérer les information supplémentaire.

    Donc, selon-vous laquelle de ces deux méthodes est la plus performante ? Aussi, laquelle est la bonne façon de faire selon ce context.

    Merci pour vos commentaires
    Mieux vaut ne rien savoir que beaucoup savoir à moitié !
    Faite vous en pas avec la vie, personne en est sortie vivant !

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 383
    Points
    18 383
    Par défaut
    La première méthode, qui est plus simple à relire, plus naturelle et qui fera un appel en moins à votre table.

    Le group by qu'il concerne une ou dix colonnes, à la rigueur on s'en moque, ça vient en fin de traitement (après les jointures, les filtres, l'utilisation des index...).

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 837
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 837
    Points : 52 922
    Points
    52 922
    Billets dans le blog
    5
    Par défaut
    Le fait que vous employez une variables table empêche toute optimisation car une telle table n'a ni clef ni index. Le fait peut paraître surprenant, mais le simple fait que votre table soit en dur et non plus temps ou var, permet au moteur de paralléliser les accès et par là même d'obtenir des temps de réponse infiniment plus rapide !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  4. #4
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Le fait que vous employez une variables table empêche toute optimisation car une telle table n'a ni clef ni index. Le fait peut paraître surprenant, mais le simple fait que votre table soit en dur et non plus temps ou var, permet au moteur de paralléliser les accès et par là même d'obtenir des temps de réponse infiniment plus rapide !

    A +
    Je m'excuse, j'aurais dû vous dire que c'est qu'une exemple. J'ai utilisé une variable table afin que vous puissez faire un "copier/coller".

    Évidemment, dans l'utilisation réelle, cela serait fait sur une table physique et doté d'index
    Mieux vaut ne rien savoir que beaucoup savoir à moitié !
    Faite vous en pas avec la vie, personne en est sortie vivant !

  5. #5
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Alors selon-vous la méthode #1 est la bonne façon de faire ?

    Selon ce que j'ai vu dans le "Plan d'exécution", la méhode #1 coute plus cher en "Sorting".

    Quant à la méthode #2, elle coute encore plus cher en "Hash Match Inner Join".

    Mais je présume que si la table serait dôté d'un index sur le EmployeeID et SubordinateID, le match innerjoin serait plus faible ? Donc, la méthode #2 serait probablement plus performante ?

    Qu'en pensez-vous ?
    Mieux vaut ne rien savoir que beaucoup savoir à moitié !
    Faite vous en pas avec la vie, personne en est sortie vivant !

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 383
    Points
    18 383
    Par défaut
    Il faut regarder le coût de la requête dans sa globalité.

    Dans la première vous faites une jointure externe et un agrégat.
    Dans la seconde vous faites une jointure externe, un agrégat, et à nouveau une jointure.

    Je reste sur ma position, la première requête sera la plus performante.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Count et group by multiple
    Par cedrick21 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 12/09/2012, 16h46
  2. GROUP BY Multiple - Que pensez-vous de ma solution ?
    Par arnolem dans le forum Requêtes
    Réponses: 4
    Dernier message: 14/09/2010, 10h16
  3. Probleme requete avec GROUP BY, optimisation, performance
    Par MatthieuFourcade dans le forum Requêtes
    Réponses: 4
    Dernier message: 10/12/2009, 11h44
  4. [XSL 2.0] Group-By multiple value
    Par kendras dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 24/04/2009, 09h04
  5. [Oracle] enregistrement multiple à cause du group by
    Par marceline dans le forum Oracle
    Réponses: 13
    Dernier message: 25/07/2006, 11h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo