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

Requêtes MySQL Discussion :

Requête SQL aux performances contre intuitives [MySQL-5.7]


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mai 2017
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2017
    Messages : 18
    Points : 14
    Points
    14
    Par défaut Requête SQL aux performances contre intuitives
    Bonjour,

    Je travaille à la construction d'une matrice de formation d'agent générée en php dans laquelle ma requête est répétée autant de fois que j'ai d'item de formation (colonne).
    Nom : apercu.jpg
Affichages : 242
Taille : 30,5 Ko
    Au delà de 7 items, la requête sql met plus 30 seconde à s’exécuter.
    Il faut évidemment creuser les performances de la requête et travailler les données pour améliorer.
    Seulement un point me bloque, si je demande la même requête sur l'ensemble des items, elle est alors très rapide sqlFull.zip.

    Pouvez vous m'orienter sur l'origine du pb ?
    Ci-dessous du code mis en forme avec en gras la séquence répétée n fois pour n items de formation (je génère dans le select une syntaxe HTML qui n'apparait pas ici d'où les "" à la place de <form>...</form> :

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    select distinct concat( "
    ") as Qui 
    , if(cat32.STATUT is null," ", cat32.STATUT) as ""
    
    from 
    
        (SELECT distinct cybele_secteur_agent.CODE_AGENT, members.nom , members.prenom FROM cybele_secteur_agent 
        inner join members on members.id=cybele_secteur_agent.code_agent WHERE cybele_secteur_agent.CODE_SECTEUR and cybele_secteur_agent.CODE_AGENT in (0,138,139,150,151,154,115))
     as agent 
    
    left join 
        (select cybele_hab_agent.CODE_AGENT, cybele_hab_agent.CODE_CAT_HAB, cybele_hab_agent.DATE_FORM, cybele_hab_agent.DATE_HAB, cybele_hab_agent.DATE_DESD_HAB_AGENT
    
        , if(cybele_hab_agent.DATE_DESD_HAB_AGENT is not null
        ,concat("+")
        , if( (susp.DATE_RETOUR_AGENT is null and datediff(now()    ,susp.mDATE_SUSP_AGENT) > cybele_cat_hab.DELAIS_REHAB) or (susp.DATE_RETOUR_AGENT is not null and datediff(susp.DATE_RETOUR_AGENT    ,susp.mDATE_SUSP_AGENT) > cybele_cat_hab.DELAIS_REHAB)    , if(maint.mDATE_MAINT is not null    , concat("a Rehabiliter")    , concat("Non Habilite"))    , if(maint.mDATE_MAINT is not null and datediff(now(),maint.mDATE_MAINT) < DELAIS-AJUSTEMENT    , if(maint.PARTIEL=1    , concat("Habilite Partiellement")    , concat("Habilite"))    , if(maint.mDATE_MAINT is not null and datediff(now()    ,maint.mDATE_MAINT) between DELAIS-AJUSTEMENT and DELAIS+AJUSTEMENT    , concat("a Maintenir")    , if(maint.mDATE_MAINT is not null and datediff(now()
        ,maint.mDATE_MAINT) > DELAIS+AJUSTEMENT    , concat("Depasse")    , if(maint.mDATE_MAINT is null and (cybele_hab_agent.DATE_FORM is not null or cybele_hab_agent.VAE=1)    , concat("Formation")    , concat("Non Habilite")))))) )    as STATUT 
    
        from cybele_hab_agent 
    
        inner join cybele_cat_hab on cybele_cat_hab.code_cat_hab=cybele_hab_agent.CODE_CAT_HAB 
    
        left JOIN
             (select cybele_agent_susp.CODE_MEMBERS, cybele_agent_susp.DATE_SUSP_AGENT as mDATE_SUSP_AGENT, cybele_agent_susp.DATE_RETOUR_AGENT 
            from cybele_agent_susp 
            inner join
                 (SELECT CODE_MEMBERS, max(DATE_SUSP_AGENT) as MaxD 
                FROM cybele_agent_susp 
                group by CODE_MEMBERS)
                    as MaxSusp on cybele_agent_susp.CODE_MEMBERS=MaxSusp.CODE_MEMBERS 
                            and cybele_agent_susp.DATE_SUSP_AGENT=MaxSusp.MaxD)
            as susp on cybele_hab_agent.CODE_AGENT=susp.CODE_MEMBERS 
            left JOIN
                (select cybele_maint_agent.CODE_AGENT
                , cybele_maint_agent.CODE_CAT_HAB
                , cybele_maint_agent.DATE_MAINT as mDATE_MAINT
                , cybele_maint_agent.COMMENTAIRE_MAINT
                , cybele_maint_agent.PARTIEL from cybele_maint_agent 
                inner join 
                    (SELECT CODE_AGENT, CODE_CAT_HAB, max(DATE_MAINT) as MaxD 
                    FROM cybele_maint_agent 
                    group by CODE_AGENT, CODE_CAT_HAB) 
                    as MaxMaint on cybele_maint_agent.CODE_AGENT=MaxMaint.CODE_AGENT 
                                and cybele_maint_agent.CODE_CAT_HAB=MaxMaint.CODE_CAT_HAB 
                                and cybele_maint_agent.DATE_MAINT=MaxMaint.MaxD) 
            as maint on cybele_hab_agent.CODE_AGENT=maint.CODE_AGENT 
                    and cybele_cat_hab.CODE_CAT_HAB=maint.CODE_CAT_HAB 
            where cybele_hab_agent.CODE_CAT_HAB=32) 
    as cat32 on agent.code_agent=cat32.code_agent 
    Merci pour votre aide

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 769
    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 769
    Points : 52 722
    Points
    52 722
    Billets dans le blog
    5
    Par défaut
    Un SGBDR est optimisé pour manipuler des ensembles de données. Pas des données unitaires.
    C'est comme un camion... Si vous utilisez un camion pour aller cherche votre paquet de clope au coin de la rue je vous souhaite bien du courage !
    En revanche si vous voulez déménager votre maison de 200 m² vous utilisez quoi ? Un vélo ? Un camion ?

    Il faudrait donc commencer par apprendre les fondamentaux

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

  3. #3
    Membre à l'essai
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mai 2017
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2017
    Messages : 18
    Points : 14
    Points
    14
    Par défaut
    Bonjour,

    Merci pour votre réponse, mais pourriez vous m'éclaircir un peu votre réponse ?
    Qu'est-ce qui vous choque dans ma requête ?
    Quelle notion fondamentale ai-je loupé ?

    est le fait de construire une sous requête par colonne ?

  4. #4
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut
    Citation Envoyé par pypeseux Voir le message
    Qu'est-ce qui vous choque dans ma requête ?
    Quelle notion fondamentale ai-je loupé ?
    Ce n'est pas dans la requête que c'est choquant, c'est dans la répétition.

    Prenez le temps de faire un schéma en séparant le serveur PHP du serveur MySQL et déroulez votre programme.
    Vous verrez que MySQL n'est pas en cause mais c'est bien votre boucle PHP qui bloque.
    Unitairement c'est invisible.
    Dès qu'on commence à augmenter le volume ça rame.

    Pourquoi croyez-vous qu'on demande de faire des tests de montée en charge ?
    Le savoir est une nourriture qui exige des efforts.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mai 2017
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2017
    Messages : 18
    Points : 14
    Points
    14
    Par défaut
    Bonjour,

    merci du temps que vous avez consacré à ma demande, malheureusement pour moi, vos réponses sont un peu trop générale pour mon niveau, débutant effectivement.

    Mais il faut bien commencer un jour non ?

    Novice en la matière je suis effectivement une formation en e-learning, et je cherchai donc quelques avis au sujet de performances non linéaires de cette requête.

    je classe le point en résolu et vais poursuivre ma formation.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut
    Citation Envoyé par pypeseux Voir le message
    Novice en la matière je suis effectivement une formation en e-learning, et je cherchai donc quelques avis au sujet de performances non linéaires de cette requête.
    En fait je n'avais pas lu la requête.
    Pour un débutant je la trouve très complexe.

    Elle fait quoi ?
    Je suis sérieux, je n'ai pas compris.
    Tu vas chercher dans plusieurs tables ( cybele_secteur_agent, members, cybele_hab_agent, cybele_cat_hab, cybele_agent_susp, cybele_maint_agent) pour avoir quel résultat ?

    Quoi qu'il en soit voici quelques remarques :
    * Distinct est couteux. si on peut s'en passer c'est mieux.
    * Left join c'est couteux. Idem.
    * Utiliser une fonction pour rien est couteux. Ex : concat("") as Qui

    * normalement les colonnes ont un nom explicite (et pas AS "") et distinct. Si tu veux reprendre ce résultat dans une "sur" requête se d'autant plus simple.

    * la fonction ISNULL remplacera agréablement : IF(cat32.statut IS NULL, "", cat32.statut) https://dev.mysql.com/doc/refman/8.0...operators.html
    * les cascades de If sont non maintenables ; lui préférer CASE https://dev.mysql.com/doc/refman/5.7/en/case.html
    * les sous requêtes ne sont pas aussi élégantes que les CTE https://dev.mysql.com/doc/refman/8.0/en/with.html
    * les alias de table permettent d'alléger le code


    Pour parler des perf il faudra passer par :
    * EXPLAIN donne le détail de la résolution du SQL https://dev.mysql.com/doc/workbench/...e-explain.html
    Mais je suis assez serein sur le fait que l'écriture est anormalement complexe et que la redéfinir sera déjà un grand pas en avant.
    Le savoir est une nourriture qui exige des efforts.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mai 2017
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2017
    Messages : 18
    Points : 14
    Points
    14
    Par défaut
    Je vais donc de ce pas dissocier mes requêtes de mon formatage de données et apporter les améliorations que tu as listées.

    Merci pour ton aide
    PY

  8. #8
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    @Michel.Priori
    D'accord sur l'essentiel à l'exception de ceci
    Citation Envoyé par Michel.Priori Voir le message
    * Left join c'est couteux.
    * les sous requêtes ne sont pas aussi élégantes que les CTE https://dev.mysql.com/doc/refman/8.0/en/with.html
    Le choix d'une jointure inner ou outer n'est pas piloté par les performances mais par le résultat qui n'est évidemment pas le même, de plus, le coût n'est pas forcément beaucoup plus important avec une jointure outer, tout dépend des cardinalités coté table OUTER
    Les CTE ne sont pas applicables avec MySQL 5.7, MySQL ne propose les CTE que depuis la V8

    Sinon, outre les judicieuses remarques de Michel, j'ajoute qu'un code "propre" facilite grandement la compréhension de la requête.
    Quelques efforts de présentation seraient les bienvenus

  9. #9
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Le choix d'une jointure inner ou outer n'est pas piloté par les performances mais par le résultat qui n'est évidemment pas le même, de plus, le coût n'est pas forcément beaucoup plus important avec une jointure outer, tout dépend des cardinalités coté table OUTER
    Les CTE ne sont pas applicables avec MySQL 5.7, MySQL ne propose les CTE que depuis la V8
    Pour la jointure outer, c'est comme pour le distinct ou le union (sans all) : c'est couteux et on s'en sert sur imposition (et non pas par défaut)
    Couteux ne veux certainement pas dire interdit

    Pour la version et ses nouvelles fonctionnalités :
    La version 8.0, en version stable, est sortie quand exactement ?
    Lorsque j'entends que le projet est en Oracle 9 (voire 8) ou en SQL 2000, je pointe toujours le problème tout en comprenant qu'au prix de la licence on hésite.
    En réalité c'est sur les licences non open source, grâce à l'arrêt du support, que les versions sont le mieux suivies.
    Ce n'est donc pas principalement une raison financière mais un vieil atavisme : "touche pas au truc qui fonctionne"
    C'est comme ça qu'on trouve encore des jointure dans le where alors que le mot clé join est officiellement adopté depuis 1992.
    Ceci dit qu'elle est la version de pypeseux ?
    Le savoir est une nourriture qui exige des efforts.

  10. #10
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut à tous.

    Quelques remarques sur votre requête :

    1) faites en sorte que votre requête soit lisible.

    2) utilisez les alias au lieu de préfixer par le nom de la table.

    3) évitez de faire de la répétition dans votre requête. Il y a plusieurs possibilités :
    --> soit de faire une view
    --> soit de faire une sous-requête
    --> soit d'utiliser les CTE (à partir de MySql 8.0)

    4) au lieu d'utiliser la fonction "if()", ou encore "ISNULL() comme il est proposé, utilisez plutôt "coalesce()". Cela fait la même chose, mais c'est plus compacte.

    5) évitez d'avoir des colonnes à NULL dans une base de données.
    Sinon pourquoi créer une ligne si celle-ci est partiellement rempli ?
    Autrement dit, vous avez un problème de modélisation.
    C'est le signe que vous n'avez pas compris ce que vous essayez d'entreprendre.

    6) évitez d'utiliser "distinct". D'ailleurs pourquoi avez-vous des lignes en doublons ?

    7) Michel.Priori fait une remarque très pertinente. Évitez d'utiliser des "IF()" en cascade.
    Vous aurez un problème de performance, mais surtout un problème de lisibilité et de maintenance.

    8) un SGBDR sert à manipuler des relation.
    Si vous avez besoin de manipuler des chaînes de caractères, comme vous le faites, créez une table avec une codification pour chaque chaîne que vous utilisez.
    Cela va simplifier l'écriture de votre requête et la rendre plus souple à l'usage. Pensez à la maintenance!

    9) éviter de faire des boucles en php. Je rappelle que la manipulation de vos données est ensembliste.
    A vous de comprendre ce que vous cherchez à faire !

    10) Evitez des sous-requêtes dans des sous-requêtes puis dans des sous-requêtes. Utilisez les jointures afin que tout soit au même niveau.

    11) pour les performances, faites l'usage des index.
    Quand vous avez un "where table_1.col1 = table_2.col2", la table_1 doit posséder un index sur "col1."

    12) si vous êtes débutant en la matière, je vous conseille d'acheter un livre sur les bonnes pratiques des SGBDR.
    De faite des exercices avant de vous attaquer à un vrai projet.
    Cela ne sert à rien de commencer par un projet si vous n'avez pas les bases pour le faire.

    13) commencez par la modélisation. Définissez vos règles !
    A partir de là, vous aurez vos entités et vos relations.
    Définissez aussi votre dictionnaire de données, puis pour chaque colonne, les règles de gestion.

    14) vous avez la chance d'avoir à votre disposition des personnes qui peuvent vous aider. Profitez-en !

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  11. #11
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Michel.Priori Voir le message
    Pour la jointure outer, c'est comme pour le distinct ou le union (sans all) : c'est couteux et on s'en sert sur imposition (et non pas par défaut)
    Couteux ne veux certainement pas dire interdit
    Sur imposition ? Qu'est-ce à dire
    On utilise une jointure outer quand on a besoin obligatoirement des éléments de la table inner même s'il n'y a pas de correspondance dans la table outer et ce indépendamment des considérations liées aux performances. Hors de question de remplacer une jointure OUTER par une jointure INNER sous prétexte d'améliorer les perfs puisque le résultat n'est pas le même.


    Citation Envoyé par Michel.Priori Voir le message
    Pour la version et ses nouvelles fonctionnalités :
    La version 8.0, en version stable, est sortie quand exactement ?
    Ceci dit qu'elle est la version de pypeseux ?
    La v8 date d'un an environ, comme indiqué dans le titre du sujet, Pypeseux utilise la version 5.7, pas de CTE donc

  12. #12
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    On utilise une jointure outer quand on a besoin [...] puisque le résultat n'est pas le même.
    Vous et moi sommes d'accord.
    Cette remarque était faite de manière générale car j'en ai déjà vu pour qui "c'est une option sécuritaire, on ne sait jamais", et ce, même quand la table enfant "jointe" la table parent.


    Citation Envoyé par escartefigue Voir le message
    La v8 date d'un an environ
    Oui.
    Ce n'est pas ma faute si cet élément de la norme SQL:1999 n'a été appliqué qu'à partir d'avril 2018...
    Bon OK, je pousse un peu.
    Mais faut bien avouer que les mises à jours trainent souvent la patte.

    Citation Envoyé par escartefigue Voir le message
    comme indiqué dans le titre du sujet, Pypeseux utilise la version 5.7, pas de CTE donc
    Et oui, pas lu le sujet
    Le savoir est une nourriture qui exige des efforts.

  13. #13
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Il faut avouer que MySQL a pris son temps pour adopter les CTE, mais aussi les fonctions OLAP et d'autres améliorations enfin portées par la V8.

    Il reste encore un peu de chemin à parcourir, sauf erreur de ma part, toujours pas de FULL OUTER JOIN par exemple

  14. #14
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut à tous.

    Pour ma part, cela ne me dérange pas trop de ne pas avoir eu, jusqu'à présent, les CTE.
    C'est juste une façon de procéder qui améliore le traitement, sans plus.
    On peut toujours trouver une solution pour contourner son absence, sauf que cela sera plus bavard sous MySql.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  15. #15
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut
    Citation Envoyé par Artemus24 Voir le message
    C'est juste une façon de procéder qui améliore le traitement
    Ça améliore la maintenance (lisibilité)
    Et en plus ça impose de formaliser sa démarche de résolution (sans, le risque de faire des sous-requête "juste parce que j'en avais besoin" est plus grand)

    Du coté de la fonctionnalité, c'est LE moyen de faire du récursif.
    OK on pouvait faire des procédures, OK on pouvait adopter l'algo intervallaire de Frédéric (pour les arbres), mais c'est quand même top d'avoir une façon "standard" qui traite tous les aspects en une seule syntaxe.
    Même si les problèmes de récursivité, c'est pas tous les jours.
    Le savoir est une nourriture qui exige des efforts.

  16. #16
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut Michel.Priori.

    Pour l'aspect lisibilité, je suis d'accord.
    Mais quand on donne un outil qui permet de faire plus, il y a toujours des gens qui vont faire n'importe quoi avec.
    Je prends le cas des procédures stockées, où je ne sais combien de fois, j'ai vu que l'on s'en servait pour faire du traitement applicatif.
    Une base de données sert à gérer des donner et uniquement cela. Comment ? Par des méthodes ensemblistes (intersection, union, ...).
    Quand je vois que l'on s'en sert pour faire de la mise en forme, ou des gros calculs qui n'ont pas lieu d'être, cela me choque.
    En fait, il y a des gens qui ne savent pas où se trouve le juste milieu entre SGBDR et langage de développement.
    Est-ce le rôle d'un SGBDR de faire de la présentation de données ? La réponse est non car c'est le rôle des langages.

    Un calcul qui dépend que des données, je veux bien. Mais j'ai plutôt tendance à faire que des extractions et le reste se fait, en mémoire, dans un programme.
    Je prends un exemple vécu où le gros du travail se faisait coté SGBDR et durait presque quatre heures.
    J'ai considérablement amélioré les performances, en faisant que des extractions (durée environ 15 minutes) depuis le SGBDR, puis le reste du traitement dans un programme (5 minutes).

    Il faut se souvenir que les accès aux données au travers d'un SGBDR sont beaucoup plus longue que de les faire en mémoire dans un programme.
    Si l'on veut manipuler des données, il vaut mieux privilégier les extractions depuis le SGBDR, et de faire le reste au travers d'un langage, en mémoire.

    Pour le récursif ? J'ai jamais rencontré des applications (de type bancaire ou de gestion) qui l'utilisent. Mais faudrait encore savoir correctement utiliser le récursif.

    Avant d'utiliser des CTE, je faisais soit des view, soit au travers des tables temporaires.
    Oui, c'est mieux, et c'est plus compacte comme approche.
    Il y a en effet des fonctionnalité qui nous simplifie la vie. Donc pourquoi ne pas les utiliser.

    Pour ma part, je les utilise très peu car la plupart du temps, je les traite d'une manière applicative.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  17. #17
    Membre à l'essai
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mai 2017
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2017
    Messages : 18
    Points : 14
    Points
    14
    Par défaut
    Bonjour Artemus24,


    2) utilisez les alias au lieu de préfixer par le nom de la table.
    Quelle différence entre mettre un alias et laisser le nom de la colonne d'origine ? Dans d'autres scripts, je n'avais pas préfixé les champs des colonnes et je trouve justement que la reprise des requêtes était moins facile... mais c'est vrai que les noms de mes tables sont longs et alourdissent la lecture.


    4) au lieu d'utiliser la fonction "if()", ou encore "ISNULL() comme il est proposé, utilisez plutôt "coalesce()". Cela fait la même chose, mais c'est plus compacte.
    Effectivement, cette proposition va bien alléger la lecture du code.

    5) évitez d'avoir des colonnes à NULL dans une base de données.
    Sinon pourquoi créer une ligne si celle-ci est partiellement rempli ?
    Autrement dit, vous avez un problème de modélisation.
    C'est le signe que vous n'avez pas compris ce que vous essayez d'entreprendre.
    Tous les champs de la base doivent contenir une information, c'est la requête d'affichage d'une matrice qui agrège des données de plusieurs secteurs mais où tous les agents ne sont pas associés à ce secteur, ma matrice doit effectivement avoir des champs null.
    C'est pour cela que j'ai eu recours systématiquement au left join avec chaque sous requête avec une table exhaustive des agents que le cadre souhaite observer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select * from
    (select agent from table_agent) as base_matrice
    left join ( statut_habilitation1 ) as habilitation1 on habilitation1.code_agent=base_matrice.code_agent
    left join ( statut_habilitation2 ) as habilitation2 on habilitation2.code_agent=base_matrice.code_agent
    left join ( statut_habilitation3 ) as habilitation1 on habilitation3.code_agent=base_matrice.code_agent
    J'ai tenté au travers de cette lourde requête de profiter de l'agrégation pour faire une mise en forme de données en colonne qui me facilite le code php, en créant un alias par habilitation, il ne me restait plus qu'à afficher le fetch de ce pdo.
    Et parce que je n'ai pas froid aux yeux ( pour ne pas m'humilier d'avantage) la fonction concat me permettait de placer du HTML en guise d'en-tête de mes colonnes.
    Rassurez vous j'ai bien compris la limite de coder à l'économie !


    6) évitez d'utiliser "distinct". D'ailleurs pourquoi avez-vous des lignes en doublons ?
    Si je n'use pas du left join par confort comme évoqué ci dessus, il est vrai qu'en phase de test, j'ai mis le distinct pour comprendre pourquoi certains résultats doublonnaient.

    7) Michel.Priori fait une remarque très pertinente. Évitez d'utiliser des "IF()" en cascade.
    Vous aurez un problème de performance, mais surtout un problème de lisibilité et de maintenance.
    Je vais tenté de convertir mon code en switch si cela améliore la lisibilté.

    12) si vous êtes débutant en la matière, je vous conseille d'acheter un livre sur les bonnes pratiques des SGBDR.
    De faite des exercices avant de vous attaquer à un vrai projet.
    Cela ne sert à rien de commencer par un projet si vous n'avez pas les bases pour le faire.
    Malheureusement, malgré le fait que mon code soit sale et plein de défaut, je suis une licence info à temps perdu dans cet objectif et cherche améliorer le quotidien de mes collègues du mieux que je le peux. Cette page WEB permettra d'économiser un temps de travail et une sécurité considérable pour les utilisateurs et j'optimiserai le tout au fur et à mesure... Cela n'est pas idéal mais je vous garantis que les excel qui trainent sur tous les postes et les bases access non maintenues, c'est pas la panacée non plus . Mon objectif et de faire au mieux ( la bdd est simpliste) au plus vite pour sécuriser la formation du personnel sous 30 jours


    13) commencez par la modélisation. Définissez vos règles !
    A partir de là, vous aurez vos entités et vos relations.
    Définissez aussi votre dictionnaire de données, puis pour chaque colonne, les règles de gestion.
    Cette remarque tombe à pique, je suis en partiel de Merise le 22/05, et je buche la doc de ma bdd dessein ;-)

    14) vous avez la chance d'avoir à votre disposition des personnes qui peuvent vous aider. Profitez-en !
    Et je vous en suis très reconnaissant

    je tiens compte des remarques auxquelles je n'ai pas répondu, mais je dois prioriser mon chantier, et je vois bien comment mettre en place cette première série.

    Merci encore

  18. #18
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut
    Citation Envoyé par Artemus24 Voir le message
    Il faut se souvenir que les accès aux données au travers d'un SGBDR sont beaucoup plus longue que de les faire en mémoire dans un programme.
    Même si je comprends le contexte et la précision du cas d'usage de cette phrase, je ne peux la laisser passer telle quelle.
    La conversation peut être très longue et le but n'est pas de polluer -de trop- le post de pypeseux.
    Si la polémique doit durer, comment créer un nouveau post ?

    Donc.
    Les SGBD travaillent tous en mémoire. Ce sont de gros consommateurs.
    Les accès aux données sont plus rapides en base que depuis un serveur déporté qui utiliserait un SGBD distant.
    Les échanges de données en RAM de serveur à serveur, je ne connais pas.
    La répartition de la charge nécessite une vision d'ensemble et, bien utilisée, c'est d'une efficacité redoutable
    Le théorème CAP montre les limites lorsqu'on veut faire de la base de donnée "répartie".
    Il n'y a pas que le stockage des données qui peut être réparti. Certains traitements peuvent l'être assez facilement. (d'ailleurs le tri ...)
    La charge de répartition ne doit pas "plomber" le réseau

    Les SGBD sont spécialisés pour faire du SQL.
    Le langage SQL est l'un des rare langage de 4ieme génération.
    Ça se paie au prix d'un champ d'action restreint "au traitement ensembliste des données vectorisées".
    Donc, :
    * non, le SQL n'est pas là pour faire de la présentation (petite pensée pour l'opérateur Rollup et la réutilisation du résultat dans une clause FROM).
    * oui, les jointures sont naturelles et bien prises en charge
    * l'optimiseur est là pour trouver le "meilleur" plan d'exécution
    * la manipulation de chaine, de pointeurs et autre calculs n'est pas un objectif premier su SQL

    Donc pour revenir à la requête de pypeseux :
    non ce n'est pas une question d'avoir froid aux yeux que de vouloir faire du HTML directement, ce n'est pas là qu'il faut le faire.
    La base traite du SQL.
    Elle produit une matrice "juste parfaite" au serveur PHP.
    Le serveur PHP traite cette matrice pour en faire quelque chose de beau et pratique.
    Chacun son rôle.

    Pour finir, pypeseux, ne vous dévalorisez pas.
    Nous ne voyons que ce que vous nous avez donné à lire.
    On s'y jette dessus pour essayer d'aller dans "la bonne direction" ; du moins il me semble que c'est l'objectif même de ce forum (et même de tous les forums techniques).
    Perso, je trouve vos posts de bonne qualité et j'apprécie le fait que vous essayez d'aller au delà de ce qui est proposé.
    Le savoir est une nourriture qui exige des efforts.

  19. #19
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut
    Citation Envoyé par pypeseux Voir le message
    5) évitez d'avoir des colonnes à NULL dans une base de données.
    Sinon pourquoi créer une ligne si celle-ci est partiellement rempli ?
    Autrement dit, vous avez un problème de modélisation.
    C'est le signe que vous n'avez pas compris ce que vous essayez d'entreprendre.


    Tous les champs de la base doivent contenir une information, c'est la requête d'affichage d'une matrice qui agrège des données de plusieurs secteurs mais où tous les agents ne sont pas associés à ce secteur, ma matrice doit effectivement avoir des champs null.
    C'est pour cela que j'ai eu recours systématiquement au left join avec chaque sous requête avec une table exhaustive des agents que le cadre souhaite observer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select * from
    (select agent from table_agent) as base_matrice
    left join ( statut_habilitation1 ) as habilitation1 on habilitation1.code_agent=base_matrice.code_agent
    left join ( statut_habilitation2 ) as habilitation2 on habilitation2.code_agent=base_matrice.code_agent
    left join ( statut_habilitation3 ) as habilitation1 on habilitation3.code_agent=base_matrice.code_agent
    Le diable se cache dans les détails
    L'exemple fourni relate un problème de modélisation.
    Laissons de coté le fait que l'alias habilitation1 est utilisé 2 fois (erreur de saisie très certainement).

    Le fait "d'indicer" le nom d'une table est en soit un mauvais signe.

    Si ce code à été fournis rapidement et que habilitation1 représente en fait une requête qui filtre une habilitation particulière (mettons "base de données") et qu'il existe 3 habilitations à afficher dans la matrice, c'est pas si mal.
    Par contre, si, habilitation1 représente une table, là il y a un problème de modélisation.
    Le savoir est une nourriture qui exige des efforts.

  20. #20
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut Michel.Priori.

    Citation Envoyé par Michel.Priori
    Même si je comprends le contexte et la précision du cas d'usage de cette phrase, je ne peux la laisser passer telle quelle.
    A priori, votre remarque démontre justement le contraire.

    Citation Envoyé par Michel.Priori
    La conversation peut être très longue et le but n'est pas de polluer -de trop- le post de pypeseux.
    Si la polémique doit durer, comment créer un nouveau post ?
    Vous avez un sacré toupet de me reprocher de soi-disant polluer le sujet alors que vous êtes à l'origine de ces questions.
    Quand on n'est pas d'accord avec quelqu'un, rabaissez l'autre en disant qu'il polémique est juste une façon de ce créditer sans argumenter.
    Il faut encore démontrer, avec des propos cohérents ce que l'on ressaye d'affirmer.
    A l'inverse de ce que vous croyez, je ne polémique pas, peut-être vous, je n'en sais rien.
    J'ai assez d'expérience en ce domaine pour savoir de quoi je parle.

    Citation Envoyé par Michel.Priori
    Les SGBD travaillent tous en mémoire. Ce sont de gros consommateurs.
    Donc les données ne sont pas stockées sur des disques durs ???
    Le gros du travail des SGBDR est justement de faire des lectures et des écritures sur des disques.

    Afin d'améliorer les temps d'accès, on stocke en mémoire (cela se paramètre dans My.ini), les derniers accès afin d'éviter toutes répétitions de lectures.
    Donc déjà si vous croyez que tout se fait en mémoire, vous n'avez rien compris au fonctionnent d'un SGBDR.

    Même si ces dernières années, il y a eu des optimisations qui ont améliorés les performances, ils sont encore d'ordre général. Pourquoi ?
    Parce qu'un programme peut gérer autrement les accès afin de les adapter au mieux de ce qu'il cherche à faire.
    Or le but d'un SGBDR est justement de ne pas faire du spécifique, mais d'utiliser des outils qui sont à notre disposition.
    Un SGBDR fait des accès physiques soit séquentiellement, soit au travers des index. Je n'en connais pas d'autre.
    Dans un programme, on peut gérer les données, au travers d'une gestion de la mémoire.

    A l'inverse de ce que vous croyez, quand le SGBDR lit une table, il ne se fait pas un seul accès à la ligne, comme cela se fait dans un programme.
    Il arrive, selon la complexité de la requête que plusieurs accès peuvent avoir lieu.
    Il existe pour cela des variables systèmes dans MySql qui démontrent ce nombre d'accès en lecture.

    Citation Envoyé par Michel.Priori
    Les SGBD sont spécialisés pour faire du SQL.
    N'importe quoi ! Le SQL est un langage sous la forme de requête pour effectuer de la manipulation des base de données de type relationnel.
    Quand vous dites SGBD cela n'englobe pas que le relationnel. La prochaine fois parlez de SGBDR.

    Citation Envoyé par Michel.Priori
    Le langage SQL est l'un des rares langage de 4ieme génération.
    Dans quel sens dois-je comprendre cette phrase ?

    Au cas où vous ne l'auriez pas compris, je parlais d'optimisation.
    Je pense que vous n'en avez rien à foutre qu'un traitement dure quatre heures, si celui-ci répond aux contraintes fonctionnelles.
    Et si vous devez vous casser la tête pour descendre ce résultat à un quatre heure, vous n'en ferrez rien.
    Mais bon, comme vous êtes un petit jeune qui croyez tout savoir, je vous laisse à vos illusions.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [2.x] requête sql, problème performance
    Par SuperArbre dans le forum Symfony
    Réponses: 3
    Dernier message: 14/01/2014, 08h59
  2. [12.5.4]Problème de performances sur requête SQL
    Par tdeco dans le forum Adaptive Server Enterprise
    Réponses: 5
    Dernier message: 25/05/2010, 22h06
  3. Performances requête SQL et parcours de ResultSet
    Par El Saigneur dans le forum JDBC
    Réponses: 9
    Dernier message: 17/05/2010, 15h54
  4. Requête SQL contre recordset
    Par Gabout dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 17/05/2008, 10h15

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