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 :

Optimisation RQT champ par ligne : multi-jointure ou une seule jointure avec if sur les champs ? [MySQL-8.0]


Sujet :

Requêtes MySQL

  1. #1
    Candidat au Club
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2020
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 55
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2020
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Optimisation RQT champ par ligne : multi-jointure ou une seule jointure avec if sur les champs ?
    Bonjour,

    J'aurais besoin d'aide afin d'optimiser au mieux une requête extrayant des données sur une table de workflow où sont enregistrées les nouvelles valeurs.


    PRINCIPES
    ====================
    Les tables :
    une table WF_TABLE (wf_table_id, wf_table_name, wf_table_valeur) enregistrant l'entité modifiée
    • wf_table_id : correspond à mà modification
    • wf_table_name correspond au nom de la table 'entité' modifiée
    • wf_table_valeur correspond à l'Id de mon entité

    une table WF_CHAMP (wf_champ_id, wf_champ_nom, wf_champ_valeur, wf_table_id) enregistrant le nom du champ et sa nouvelle valeur

    J'ai donc pour chaque entité modifiée dans WF_TABLE, autant de lignes dans WF_CHAMP que de champs modifiés (chaque ligne stockant le nom de la colonne dans wf_champ_name et la nouvelle valeur dans wf_champ_valeur)

    Je dois faire une extraction/tableau de afin de visualiser les nouvelles valeurs pour chaque entité modifiées avec une ligne par entités et autant de colonnes que de champs à afficher ds le tableau
    (le nb de colonne du tableau n'est pas dynamique en fonction du nb de champ modifié, il est fixé dans la RQT, mais pourra éventuellement varier en fonction du besoin qui évolue et du nb de colonnes à visualiser)

    Je précise que l'extraction que je dois faire se fait sur un type d'entité (le système de workflow étant générique à plusiuers entité dans ma base),

    SOLUTIONS
    ===============================
    Je vois 2 façons de le faire :
    A/ MULTI JOINTURE : 1 jointure sur la table des champs pour chaque champ à visualiser
    • celle sur laquelle j'irai en premier
    • j'alias ma table wf_champ à chaque fois avec la condition wf_champ_name='nom_champ_voulu'
    • mais bcp de jointure si je dois visualiser/remonter bcp de champs

    B/ JOINTURE UNIQUE : 1 seule jointure sur la table des champs wf_champ
    • une idée pour éviter d'écrire 50 jointures mais je sais pas si c'est pertinent
    • dans mon select pour chaque colonne/champ que je veux remonter je fais if(wf_champ_name='nom_champ_voulu',wf_champ_valeur,null)
    • mais du coup, ça me remonte pour chaque entité modifiée autant de lignes que de champ souhaités, pour chaque ligne seule le champ souhaité etant rempli, les autres à null
    • du coup il faut agrégé , je pensais le faire via un max() sur chaque champ remonté



    SQL A :
    ---------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT 
    	T.wf_table_name, T.wf_table_valeur,
    	C1.wf_champ_valeur 'CHAMP1', C2.wf_champ_valeur 'CHAMP2', C3.wf_champ_valeur 'CHAMP3' -- etc ... autant de fois que de champ et de jointure 
    from WF_TABLE T
    	LEFT OUTER JOIN WF_CHAMP C1 on T.wf_table_id=C1.wf_table_id and C1.wf_champ_name='champ1'
    	LEFT OUTER JOIN WF_CHAMP C2 on T.wf_table_id=C2.wf_table_id and C2.wf_champ_name='champ2'
    	LEFT OUTER JOIN WF_CHAMP C3 on T.wf_table_id=C3.wf_table_id and C3.wf_champ_name='champ3'
    	--- autant de jointure que de champs souhaités
    SQL B :
    ---------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT 
    	T.wf_table_name, T.wf_table_valeur,
    	MAX(IF(wf_champ_name='champ1',wf_champ_valeur,null)) 'CHAMP1'
    	MAX(IF(wf_champ_name='champ2',wf_champ_valeur,null)) 'CHAMP2'
    	MAX(IF(wf_champ_name='champ3',wf_champ_valeur,null)) 'CHAMP3'
    from WF_TABLE T
    	LEFT OUTER JOIN WF_CHAMP CHAMPS on T.wf_table_id=CHAMPS.wf_table_id


    Alors selon vous, je reste sur ma première idée de multi jointure ? ou la seconde solution est-elle meilleure ?
    Qu'estce qui coûte le moins, qui est plus performant ?
    - multi-jointure ramenant chacune une ligne ?
    - ou mono jointure avec MAX et un IF sur chaque colone du select ?


    Merci d'avance pour le conseil

  2. #2
    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
    Bonjour,

    Si dans la première table, j'ai par exemple wf_table_id qui représente la table des clients et que je modifie deux clients différents, comment savoir ensuite que telle valeur de telle colonne dans la table WF_CHAMP correspond au premier ou au deuxième client ?
    Il semble manquer l'identifiant PK permettant de s'y retrouver.
    De plus, comme le type et la longueur de la PK peut varier d'une table à l'autre, comment gérez vous ce cas ?

    Et aussi et surtout, quel est le but fonctionnel de tout ça ?

  3. #3
    Candidat au Club
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2020
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 55
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2020
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Bonjour,

    effectivement, on révisant les noms pour publication et pour simplifier j'ai oublié un élément. la table wf_table est comme ceci (wf_table_id, wf_table_name, wf_clenom, wf_table_valeur)
    En fait wf_table_id correspond à la l'ID de la modification, comme un id de version en fait.
    wf_table_name, correspond au nom de la table
    wf_table_clenom est le nom de la colonne sur laquelle il y a une clé primaire
    wf_table_valeur est l'id de de l'entité

    Donc dans le cas de figure ci-dessous, si la table client s'appelle T_CLIENT et que l'on modifie les clients 90 et 125 on aura
    wf_table_id wf_table_name wf_table_clenom wf_table_valeur
    5001 T_CLIENT cli_id 90
    5002 T_CLIENT cli_id 125
    Donc la modif 5001 concernant le client 90 et la modif 5002 concernant le client 125


    Si on continue l'exemple pour comprendre le fonctionnement avec les champs
    - La modif 5001 du client 90 concerne son Nom et son prenom
    - la modif 5002 du client 125 concerne son adresse et son code postal
    on aura alors :
    wf_champ_id wf_champ_nom wf_champ_valeur wf_table_id
    6001 cli_nom nouveau-nom 5001
    6002 cli_prenom nouveau-prenom 5001
    6003 cli_adr nouvelle adresse 5002
    6004 cli_cpo 75000 5002
    Donc la modif #6001 des champs concerne le champ cli_nom de la modif 'globale' 5001 (donc le cli_id 90) avec comme nouvelle valeur "nouveau-nom"
    et la modif #6003 des champs concerne le le champ cli_adr de la la modif 'globale' 5002 (donc le cli_id 125) avec comme nouvelle valeur "nouvelle adresse"
    etc ....


    Le besoin fonctionnel derrière est le suivant :
    - nous avons des users qui modifie des données via un extranet
    - nous avons une équipe métier qui valide ses données via un backoffice, la validation permettant la MAJ des champs définitif en bdd, mais avec possibilité d'annuler les modif (et 2 voir les valeurs ancienne / nouvelle dans la backoffice)
    - d'où ces tables de workflow permettant de stocker temporairement les nouvelles valeurs avant validation et enregistrement dans les tables définitives
    - je dois extraire certaines données du workflow pour faire un tableau de bord permettant à l'équipe métier de prioriser la validation de certaines modifications avant d'autres en fonction des données qui sont modifiées (certaines modifs étant considéré plus importantes que d'autres par le métier)


    Merci de votre aide

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 770
    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 770
    Points : 52 726
    Points
    52 726
    Billets dans le blog
    5
    Par défaut
    Aucune optimisation n'est possible dans ce type de modélisation qui est une aberration et viole toutes les règles de modélisation. Les requêtes seront toujours lentes et de plus en plus en fonction de la montée en charge...
    Ceci est parfaitement expliquée par Stéphane Faroult dans une vidéo datant d'une vingtaine d'années, sur ce qu'il ne faut pas faire dans un SGBDR !


    Bref, concevez une base relationnelles et les performances seront au rendez-vous....

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

  5. #5
    Candidat au Club
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2020
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 55
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2020
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Bonjour,

    je me doutais de l'impossibilté de cette optimisation.
    Je suis donc parti sur la solution A avec les jointures.

    Quant à la conception de base de données, bien que n'étant pas aussi expert que vous, j'ai quand même quelques bases et j'ai bien conscience des problèmes de ce schéma
    Mais j'en hérite et n'en suis pas à l'origine.

    Merci toutefois pour votre réponse, je regarderai la vidéo avec intérêt.

    Cordialement,

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

Discussions similaires

  1. [XL-2013] Fusionner 2 lignes ou plus en une seule en se basant sur une condition sur les dates.
    Par aymen.fst dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 06/02/2019, 13h36
  2. Traiter ligne par ligne le résultat d'une requête
    Par pupucette dans le forum PL/SQL
    Réponses: 40
    Dernier message: 22/05/2012, 14h31
  3. Réponses: 8
    Dernier message: 04/07/2011, 14h16
  4. Multi jointure avec jointure externe
    Par gueulederack dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 26/03/2009, 15h52
  5. optimiser un traitement par du multi-threading
    Par in dans le forum Général Java
    Réponses: 10
    Dernier message: 10/10/2006, 09h46

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