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

Langage SQL Discussion :

Group by et dépendance fonctionnelle : Performance ?


Sujet :

Langage SQL

  1. #1
    Membre du Club Avatar de xanav
    Inscrit en
    Mars 2010
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 55
    Points : 53
    Points
    53
    Par défaut Group by et dépendance fonctionnelle : Performance ?
    J'ai pas mal cherché sur le net et on trouve du pour et du contre. Donc j'en appelle aux pros du SQL qui ont un retour d'expérience.

    Ma question est la suivante : Lorsque des colonnes sont fonctionnellement liées et qu'on veut faire un group by, vaut-il mieux mettre tous les champs dans le group by ou faire une agrégation inutile ?

    Concrètement laquelle de ces 2 requêtes sera la plus performante ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT CLI.CLI_ID, MIN(CLI.CLI_NOM), COUNT(CDE.CDE_ID) FROM CLIENT CLI
      JOIN COMMANDE CDE ON CDE.CLI_ID = CLI.CLI_ID
      GROUP BY CLI.CLI_ID
    Ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT CLI.CLI_ID, CLI.CLI_NOM, COUNT(CDE.CDE_ID) FROM CLIENT CLI
      JOIN COMMANDE CDE ON CDE.CLI_ID = CLI.CLI_ID
      GROUP BY CLI.CLI_ID, CLI.CLI_NOM
    Et je ne parle pas de MySQL, qui d'après ce que j'ai lu autorise de sélectionner des champs non groupés.
    Personnellement, j'utilisais toujours la 1ère syntaxe mais aujourd'hui je me retrouve coincé avec un type bit sur lequel on ne peut pas faire de MIN ou MAX. Du coup, entre le mettre dans le group by ou faire un cast vers INT, pour faire un min puis refaire un cast faire bit, j'hésite...
    Notre connaissance est finie, notre ignorance est infinie.

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    C'est clairement la deuxième requête qui est à la fois la plus logique, la plus claire, la plus propre !

    En lisant la première, je me suis demandé s'il n'y avait pas carrément une faute de frappe et que ce qui était recherché était la première commande du client par le plus petit id de commande associé au client !

    En demandant au SGBD de chercher le MIN(CLI.CLI_NOM) pour un client, tu lui demandes du travail inutile puisqu'un client n'a qu'un seul nom !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Membre du Club Avatar de xanav
    Inscrit en
    Mars 2010
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 55
    Points : 53
    Points
    53
    Par défaut
    Bah en fait, dans ma logique (qui n'est visiblement pas partagée de tous ) je me disais que dans les 2 cas, on fait travailler le SGBD pour rien :
    - Soit on lui dit de calculer le minimum sur 1 valeur
    - Soit on lui dit de regrouper suivant un champ qui ne possède toujours qu'une valeur pour le précédent regroupement.

    Du coup je pensais que c'était peut-être plus rapide de calculer le minimum que de regrouper...
    En fait, le plus logique (encore une fois, pour moi...) ça serait une fonction d’agrégation FIRST() qui prendrait la 1ère valeur trouvée sans se poser de question.
    Notre connaissance est finie, notre ignorance est infinie.

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Il faudrait qu'un spécialiste du fonctionnement interne des SGBD réponde mais j'ose espérer que les développeurs de ceux-ci ont pensé à intégrer dans les algorithmes que le fait de regrouper sur une clé primaire (CLI_ID) implique de prendre sans se poser de question les valeurs des autres colonnes de la même table associées à la clé si elles sont demandées.
    Donc, à mon avis, le SGBD ne fait pas d'opération de groupage sur CLI_NOM mais prend la valeur de CLI_NOM associée à la valeur de la clé CLI_ID sur laquelle il effectue le groupage.

    S'il s'agit d'une requête de groupage avec jointure(s), je pense que le SGBD commence par joindre les tables, y appliquer les restrictions (WHERE) éventuelles puis fait le groupage sur le jeu de résultats.

    Et comme, si je ne me trompe, le résultat d'une jointure entre deux relations (au sens théorie relationnelle) est une relation, le SGBD doit logiquement chercher la clé de cette relation résultante et procéder de la même manière que s'il n'y avait qu'une relation (table) dans la requête.

    À confirmer par plus expert que moi sur ces sujets.

    En fait, le plus logique (encore une fois, pour moi...) ça serait une fonction d’agrégation FIRST() qui prendrait la 1ère valeur trouvée sans se poser de question.
    Ça c'est ce que fait le mauvais MySQL qui autorise de ne pas mettre dans le GROUP BY toutes les colonnes du SELECT ne faisant pas l'objet d'une fonction de groupage. Ainsi, MySQL autoriserait que ta requête ait ce groupage : GROUP BY CLI_ID avec le même SELECT.
    Ça donnerait un résultat juste dans le cas de cette requête puisque CLI_NOM dépend directement de CLI_ID mais ça pourrait donner un résultat faux dans une requête avec jointure.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 774
    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 774
    Points : 52 743
    Points
    52 743
    Billets dans le blog
    5
    Par défaut
    Tout dépend de l'optimiseur. Dans un SGBDR haut de gamme genre Oracle ou mieux SQL Server, l'optimiseur va récrire la requête au niveau de l'algébrisation afin de la simplifier. Ce n'est pas le cas par exemple de MySQL dont l'optimiseur est quasi inexistant... Quand à PG, de notables progrès sont encore à faire...

    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/ * * * * *

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Tout dépend de l'optimiseur. Dans un SGBDR haut de gamme genre Oracle ou mieux SQL Server, l'optimiseur va récrire la requête au niveau de l'algébrisation afin de la simplifier.
    Tu veux dire que ces SGBD vont supprimer le MIN de la première requête de xanav ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  7. #7
    Membre du Club Avatar de xanav
    Inscrit en
    Mars 2010
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 55
    Points : 53
    Points
    53
    Par défaut Et le vainqueur est ... GROUP BY
    Effectivement, après quelque tests sur les temps de réponse sous SQL Server, il n'y a pas photo : Mettre le champ dans le GROUP BY est plus rapide que mettre un MIN().
    Même sur une requête aussi simple que dans l'exemple, les temps de réponse sur mes tables sont les suivant :
    - Requête 1 (avec le MIN) : environ 380 millisecondes
    - Requête 2 (avec le GROUP BY) : environ 230 millisecondes

    Et plus je rajoute de champs de la table client, plus l'écart augmente. En fait, le temps d'exécution de la requête 2 ne varie pas alors que l'autre augmente.

    Petite précision : Il semblerait que sur une table qui ne possède pas de clé primaire (rhô !!! pas bien !!!) le résultat soit différent. Ça vaudrait donc le coup de tester avec un regroupement sur un champ qui ne soit pas forcément une clé...

    Merci pour vos réponses, qui nous en apprennent un peu plus chaque jour.
    Notre connaissance est finie, notre ignorance est infinie.

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

Discussions similaires

  1. Définition d'une dépendance fonctionnelle élémentaire ?
    Par Didine1801 dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 30/11/2010, 16h59
  2. dépendance fonctionnelle en SQL
    Par moimoi_1 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 05/09/2005, 07h55
  3. ODBC et les dépendances fonctionnelles
    Par LordBob dans le forum MFC
    Réponses: 4
    Dernier message: 08/07/2005, 10h05
  4. dépendances fonctionnelles
    Par aaronw dans le forum Langage SQL
    Réponses: 4
    Dernier message: 27/05/2005, 14h39
  5. [Concept] Dépendances fonctionnelles
    Par bolo dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 24/01/2003, 20h13

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