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 qui met trop de temps à s'exécuter


Sujet :

Requêtes MySQL

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Novembre 2014
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Requête SQL qui met trop de temps à s'exécuter
    mon requête s’exécute et marche bien mais je comprend pas pourquoi elle se met trop de temps à s’exécuter.
    pouvez-vous m'aider à régler ce genre de problème?

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 088
    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 088
    Points : 38 393
    Points
    38 393
    Billets dans le blog
    9
    Par défaut
    bonjour,

    Sans la requete ni la description de vos tables et index, ni une idée du volume à traiter, ce sera bien difficile

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Novembre 2014
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Voici la requête alors,
    Code php : 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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    $reqB = 'SELECT CP.id_coresponsabilite_paiement as rang_beneficiaire,
           CP.id_registre_activite,
           CP.id_coresponsabilite_periode_paiement,
           coalesce(CP.montant_paye,"") as montant_payer,
           CP.id_agence_paiement,
           CONCAT(M.num_appel,"/",M.num_adhesion) as num_appel_adhesion,
           CP.is_valid,
           CP.regul_avenant,
           coalesce(CP.solde_ant_non_ou_trop_percu,"") as solde_ant_non_ou_trop_percu,
           CPP.nom_periode,
           CPP.date_debut,
           CPP.date_fin,
           RA.id_activite,
           RA.id_menage_valider,
           coalesce(RA.montant_prev,"") as Montant_prev,
           MV.id_questionnaire_critere,
           ME.id_menage_enquete,
           CONCAT(M.nom_chef_de_menage,"",COALESCE(M.prenom_chef_de_menage,"")) as NOM,
           M.*,
           F.nom_fokontany,
           AP.nom_agence_paiement,
           CP.montant_base as Montant_base,
           CP.montant_incitation,
           CP.montant_bonus as Montant_bonnus,
           (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0")) as periode_a_payer,
           (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    			+ coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0") as total_,
           (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    			+ coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0")
    			+ coalesce(IF(ft.pourcentage = 1,(((coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    				+ coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0")) * 
    				CASE 
    					WHEN (coalesce(CP.montant_base,"0")	+ coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0")) 
    						+ coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0") < min 
    					THEN 0 
    					ELSE coalesce(ft.montant,0) 
    				END) / 100,
    				CASE 
    					WHEN (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    						+ coalesce(  CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0")  < min
    					THEN 0 
    					ELSE coalesce(ft.montant,0)
    				END),"0") as total_payer,
    		IF(ft.pourcentage = 1,(((coalesce(CP.montant_base,0) + coalesce(CP.montant_bonus,0) + coalesce(CP.montant_incitation,0))
    			+ coalesce(CP.solde_ant_non_ou_trop_percu,0) + coalesce(CP.regul_avenant,0)) * 
    			CASE 
    				WHEN (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    					+ coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0")  < min 
    				THEN 0 
    				ELSE coalesce(ft.montant,0) 
    			END) / 100,
    			CASE 
    				WHEN (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    					+ coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0")  < min 
    				THEN 0 
    				ELSE coalesce(ft.montant,0)
    			END) as frais_retrait,
    		coalesce(ft.min,0) as min,
    		coalesce(ft.max,0) as max,
    		coalesce(ft.id_frais_de_transfert,0)
    FROM coresponsabilite_paiement as CP INNER JOIN registre_activite as RA ON CP.id_registre_activite = RA.id_registre_activite 
    	INNER JOIN menage_valider as MV ON RA.id_menage_valider = MV.id_menage_valider
    	INNER JOIN menage_a_enqueter as ME ON MV.id_menage_enquete = ME.id_menage_enquete 
    	INNER JOIN activite as A ON RA.id_activite = A.id_activite
    	INNER JOIN menage as M ON ME.id_menage = M.id_menage
    	INNER JOIN fokontany as F ON M.id_fokontany = F.id_fokontany 
    	LEFT JOIN coresponsabilite_periode_paiement as CPP ON CP.id_coresponsabilite_periode_paiement = CPP.id_coresponsabilite_periode_paiement 
    	LEFT JOIN presence_registre_semaine as PGS ON RA.id_registre_activite = PGS.id_registre_activite
    	LEFT JOIN agence_paiement as AP ON CP.id_agence_paiement = AP.id_agence_paiement
    	LEFT JOIN frais_de_transfert ft ON ft.id_agence_paiement = CP.id_agence_paiement  
    '.$where.''.$periode.' AND (is_valid IS null OR is_valid = 1) AND is_rapprochement = 0';
     
    $reqB =  ''.$reqB.' GROUP BY CP.id_coresponsabilite_paiement, ft.id_frais_de_transfert HAVING total_ >= min AND total_ <= max
    	UNION '.$reqB.' GROUP BY CP.id_coresponsabilite_paiement, ft.id_frais_de_transfert HAVING total_ < min OR total_ > max'

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 088
    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 088
    Points : 38 393
    Points
    38 393
    Billets dans le blog
    9
    Par défaut
    Quelques remarques :

    - utilisez les balises code et fin code (symbole # dans la barre d'outils) pour encadrer vos requetes

    - formatez vos requetes, c'est plus facile et lire et donc à comprendre et optimiser... il existe des sites qui peuvent vous faciliter la présentation, exemple : http://sqlformat.org/

    - votre prédicat where est invalide, ce n'est donc pas exactement cette requete qui est envoyée au moteur de votre base de données, il faut communiquer la requete qui est vraiment exécutée

    - sans la description des index, difficile de faire des analyses, disons seulement que vos prédicats de jointures semblent OK (mais sans DDL...) du coup, c'est le where qui doit piloter la non performance, communiquez le sous format lisible

    - la fin de votre requete est illisible, on y trouve pèle mèle des groupages incohérents avec la clause select, une union (sans all) peu propice aux performances, un OR dans le where source potentielle de dégradation. La aussi, corrigez votre envoi, cette fin de code est suspecte à tout point de vue

  5. #5
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Requête difficile à lire en effet. Postez plutôt la vraie requête générée.

    il me semble que vous pouvez vous passer du UNION en combinant les clauses HAVING qui sont a priori les seules à différer... mais elles me semblent parfaitement contradictoires (ou plutôt complémentaires donc inutiles)... quel est le but de la requete ?

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Novembre 2014
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Voici le code complet, j'ai changé l’opérateur OR dans where par || et la requête fonctionne encore bien mais le problème de temps d’exécution très élevée persiste toujours.

    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
     
    if ($table == "coresponsabilite") {
    	$reqB = ' SELECT CP.id_coresponsabilite_paiement as rang_beneficiaire,
                        CP.id_registre_activite,
                        CP.id_coresponsabilite_periode_paiement,
                        coalesce(CP.montant_paye,"") as montant_payer,
                        CP.id_agence_paiement,
                        CONCAT(M.num_appel,"/",M.num_adhesion) as num_appel_adhesion,
                        CP.is_valid,
                        CP.regul_avenant,
                        coalesce(CP.solde_ant_non_ou_trop_percu,"") as solde_ant_non_ou_trop_percu,
                        CPP.nom_periode,
                        CPP.date_debut,
                        CPP.date_fin,
                        RA.id_activite,
                        RA.id_menage_valider,
                        coalesce(RA.montant_prev,"") as Montant_prev,
                        MV.id_questionnaire_critere,
                        ME.id_menage_enquete,
                        CONCAT(M.nom_chef_de_menage,"",COALESCE(M.prenom_chef_de_menage,"")) as NOM,
                        M.*,
                        F.nom_fokontany,
                        AP.nom_agence_paiement,
                        CP.montant_base as Montant_base,
                        CP.montant_incitation,
                        CP.montant_bonus as Montant_bonnus,
                        (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0")) as periode_a_payer,
                        (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    						+ coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0") as total_,
                        (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    						+ coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0")
    						+ coalesce(IF(ft.pourcentage = 1,(((coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    							+ coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0")) *
    							CASE 
    								WHEN (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    									+ coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0") < min 
    								THEN 0 
    								ELSE coalesce(ft.montant,0) 
    							END) / 100,
    							CASE 
    								WHEN (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    									+ coalesce(  CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0")  < min
    								THEN 0
    								ELSE coalesce(ft.montant,0)
    							END),"0") as total_payer,
     
    					IF(ft.pourcentage = 1,(((coalesce(CP.montant_base,0) + coalesce(CP.montant_bonus,0) + coalesce(CP.montant_incitation,0))
    						+ coalesce(  CP.solde_ant_non_ou_trop_percu,0) + coalesce(CP.regul_avenant,0)) * 
    						CASE
    							WHEN (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    								+ coalesce(  CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0")  < min 
    							THEN 0
    							ELSE coalesce(ft.montant,0)
    						END) / 100,
    						CASE 
    							WHEN (coalesce(CP.montant_base,"0") + coalesce(CP.montant_bonus,"0") + coalesce(CP.montant_incitation,"0"))
    								+ coalesce(  CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_avenant,"0")  < min 
    							THEN 0
    							ELSE coalesce(ft.montant,0) END) as frais_retrait ,
    				    coalesce(ft.min,0) as min,coalesce(ft.max,0) as max,coalesce(ft.id_frais_de_transfert,0)
    				FROM coresponsabilite_paiement as CP INNER JOIN registre_activite as RA ON CP.id_registre_activite = RA.id_registre_activite 
    				INNER JOIN menage_valider as MV ON RA.id_menage_valider = MV.id_menage_valider
    			    INNER JOIN menage_a_enqueter as ME ON MV.id_menage_enquete = ME.id_menage_enquete 
    			    INNER JOIN activite as A ON RA.id_activite = A.id_activite
    			    INNER JOIN menage as M ON ME.id_menage = M.id_menage
    			    INNER JOIN fokontany as F ON M.id_fokontany = F.id_fokontany 
    				LEFT JOIN coresponsabilite_periode_paiement as CPP ON CP.id_coresponsabilite_periode_paiement = CPP.id_coresponsabilite_periode_paiement 
    			    LEFT JOIN presence_registre_semaine as PGS ON RA.id_registre_activite = PGS.id_registre_activite
    				LEFT JOIN agence_paiement as AP ON CP.id_agence_paiement = AP.id_agence_paiement
    				LEFT JOIN frais_de_transfert ft ON ft.id_agence_paiement = CP.id_agence_paiement  
     
     			'.$where.''.$periode.' AND (is_valid IS null || is_valid = 1) AND is_rapprochement = 0';
    			$reqB =  ''.$reqB.' GROUP BY CP.id_coresponsabilite_paiement,ft.id_frais_de_transfert HAVING total_ >= min AND total_ <= max
    			UNION '.$reqB.' GROUP BY CP.id_coresponsabilite_paiement,ft.id_frais_de_transfert HAVING total_ < min  OR total_ > max';
    }
    else {$reqB = 'SELECT CP.id_presence_paiement as rang_beneficiaire,
    				CP.id_registre_activite,CP.id_presence_periode_paiement,
    				coalesce(CP.montant_paye,"") as montant_payer,
                    CP.id_agence_paiement,
    				CONCAT(M.num_appel,"/",M.num_adhesion) as num_appel_adhesion,
                    CP.montant_paye,
    				CP.is_valid,
    				CP.solde_ant_non_ou_trop_percu,
    				CPP.nom_periode,
    				coalesce(CP.nb_jours_travailles ,0) as nbr_jours,
    				coalesce(CP.taux_journalier ,0) as taux,
    				CP.regul_erreur_presence as regul_erreur_presence,
                    CPP.date_debut,
    				CPP.date_fin,
    				DATEDIFF(CPP.date_fin,CPP.date_debut) as nbr_jours_periode,
    				RA.id_activite,
                    RA.id_menage_valider,
    				coalesce(RA.montant_prev,"") as Montant_prev,
    				MV.id_questionnaire_critere,
                    ME.id_menage_enquete,
    				CONCAT (M.nom_chef_de_menage," ",coalesce(M.prenom_chef_de_menage, "")) as NOM,
                    M.*,
    				F.nom_fokontany,
    				AP.nom_agence_paiement,
    				(coalesce(CP.nb_jours_travailles ,0) * coalesce(CP.taux_journalier ,0)) as periode_a_payer,
    				coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_erreur_presence,"0") + (coalesce(CP.nb_jours_travailles ,0) * coalesce(CP.taux_journalier ,0)) as total_,
    				IF(ft.pourcentage = 1,((coalesce(CP.solde_ant_non_ou_trop_percu,0) + coalesce(CP.regul_erreur_presence,0) + 
                    (coalesce(CP.nb_jours_travailles ,0) * coalesce(CP.taux_journalier ,0))) * 
    					CASE
    						WHEN coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_erreur_presence,"0")
    							+ (coalesce(CP.nb_jours_travailles ,0) * coalesce(CP.taux_journalier ,0)) < min 
    						THEN 0
    						ELSE coalesce(ft.montant,0),
    					CASE 
    						WHEN coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_erreur_presence,"0")
    							+ coalesce(CP.nb_jours_travailles ,0) * coalesce(CP.taux_journalier ,0)) < min 
    						THEN 0
    					    ELSE coalesce(ft.montant,0)
    					END) as frais_retrait,
    				(coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_erreur_presence,"0") + 
                    (coalesce(CP.nb_jours_travailles ,0) * coalesce(CP.taux_journalier ,0)))
    					+ (coalesce(IF(ft.pourcentage = 1,((coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_erreur_presence,"0")
    					+ (coalesce(CP.nb_jours_travailles ,0) * coalesce(CP.taux_journalier ,0))) * 
    					CASE
    						WHEN coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_erreur_presence,"0") + 
    							(COALESCE(CP.nb_jours_travailles ,0) * COALESCE(CP.taux_journalier ,0)) < min 
    						THEN 0
    						ELSE coalesce(ft.montant,0)
    					END  ) / 100,
    					CASE
    						WHEN coalesce(CP.solde_ant_non_ou_trop_percu,"0") + coalesce(CP.regul_erreur_presence,"0") + 
    							(coalesce(CP.nb_jours_travailles ,0) * coalesce(CP.taux_journalier ,0)) < min 
    						THEN 0
    						ELSE coalesce(ft.montant,0)
    					END),"0")) as total_payer, 
     
    				coalesce(ft.min,0) as min,
    				coalesce(ft.max,0) as max,
    				coalesce(ft.id_frais_de_transfert,0),
    				PGS.num_equipe FROM presence_paiement as CP 
                     	 LEFT JOIN presence_periode_paiement as CPP 
                     	 ON CP.id_presence_periode_paiement = CPP.id_presence_periode_paiement
                     	 INNER JOIN registre_activite as RA
                     	 ON CP.id_registre_activite = RA.id_registre_activite 
                     	 INNER JOIN menage_valider as MV ON
                     	 RA.id_menage_valider = MV.id_menage_valider 
                     	 INNER JOIN menage_a_enqueter as ME 
                     	 ON MV.id_menage_enquete = ME.id_menage_enquete 
    					 INNER JOIN activite as A ON RA.id_activite = A.id_activite
      					 INNER JOIN menage as M ON ME.id_menage = M.id_menage
                     	 INNER JOIN fokontany as F ON M.id_fokontany = F.id_fokontany 
                     	 LEFT JOIN presence_registre_semaine as PGS ON (RA.id_registre_activite = PGS.id_registre_activite 
    						AND PGS.num_semaine BETWEEN WEEK(CPP.date_debut) AND WEEK(CPP.date_fin) )
                     	 LEFT JOIN agence_paiement as AP ON CP.id_agence_paiement = AP.id_agence_paiement
    					 LEFT JOIN frais_de_transfert ft ON ft.id_agence_paiement = CP.id_agence_paiement   
     
                '.$where.''.$periode.' AND (is_valid IS null || is_valid = 1) ';
    			$reqB =  ''.$reqB.' GROUP BY CP.id_presence_paiement,ft.id_frais_de_transfert HAVING total_ >= min AND total_ <= max
    				UNION '.$reqB.' GROUP BY CP.id_presence_paiement,ft.id_frais_de_transfert HAVING total_ < min OR total_ > max';
    		}

  7. #7
    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 346
    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 346
    Points : 18 958
    Points
    18 958
    Par défaut
    Salut à tous.

    Citation Envoyé par Escartefigue
    Sans la requête ni la description de vos tables et index, ni une idée du volume à traiter, ce sera bien difficile
    @ toky23 : sans le descriptifs de vos tables et index, il est impossible de résoudre votre problème de performance !
    Et si ça se trouve, vos tables ont été mal conçues !!!

    De plus, on vous a demandé de mettre en forme votre requête, ce que vous n'avez toujours pas fait.
    La moindre des choses, si vous voulez que l'on vous aide, c'est d'être respectueux des règles de ce forum.
    J'ai mis votre requête en forme, et c'est du n'importe quoi votre façon de codifier :
    [code]
    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    SELECT          CP.id_coresponsabilite_paiement                                  as rang_beneficiaire,
                    CP.id_registre_activite,
                    CP.id_coresponsabilite_periode_paiement,
           coalesce(CP.montant_paye,"")                                              as montant_payer,
                    CP.id_agence_paiement,
              CONCAT(M.num_appel,"/",M.num_adhesion)                                 as num_appel_adhesion,
                    CP.is_valid,
                    CP.regul_avenant,
           coalesce(CP.solde_ant_non_ou_trop_percu,"")                               as solde_ant_non_ou_trop_percu,
                   CPP.nom_periode,
                   CPP.date_debut,
                   CPP.date_fin,
                    RA.id_activite,
                    RA.id_menage_valider,
           coalesce(RA.montant_prev,"")                                              as Montant_prev,
                    MV.id_questionnaire_critere,
                    ME.id_menage_enquete,
              CONCAT(M.nom_chef_de_menage,"",COALESCE(M.prenom_chef_de_menage,""))   as NOM,
                     M.*,
                     F.nom_fokontany,
                    AP.nom_agence_paiement,
                    CP.montant_base                                                  as Montant_base,
                    CP.montant_incitation                                            as Montant_incitation,
                    CP.montant_bonus                                                 as Montant_bonnus,
     
          (coalesce(CP.montant_base,                "0")  +
           coalesce(CP.montant_bonus,               "0")  +
           coalesce(CP.montant_incitation,          "0"))                            as periode_a_payer,
     
          (coalesce(CP.montant_base,                "0")  +
           coalesce(CP.montant_bonus,               "0")  +
           coalesce(CP.montant_incitation,          "0")) +
           coalesce(CP.solde_ant_non_ou_trop_percu, "0")  +
           coalesce(CP.regul_avenant,               "0")                             as total_,
     
          (coalesce(CP.montant_base,                "0")  +
           coalesce(CP.montant_bonus,               "0")  +
           coalesce(CP.montant_incitation,          "0")) +
           coalesce(CP.solde_ant_non_ou_trop_percu, "0")  +
           coalesce(CP.regul_avenant,               "0")  +
           coalesce(IF(ft.pourcentage = 1,(((coalesce(CP.montant_base,                "0")  +
                                             coalesce(CP.montant_bonus,               "0")  +
                                             coalesce(CP.montant_incitation,          "0")) +
                                             coalesce(CP.solde_ant_non_ou_trop_percu, "0")  +
                                             coalesce(CP.regul_avenant,               "0")) * 
           CASE WHEN (coalesce(CP.montant_base,                "0")  +
                      coalesce(CP.montant_bonus,               "0")  +
                      coalesce(CP.montant_incitation,          "0")) +
                      coalesce(CP.solde_ant_non_ou_trop_percu, "0")  +
                      coalesce(CP.regul_avenant,               "0")  < min 
                THEN  0
                ELSE  coalesce(ft.montant,                      0) 
                END) / 100,
     
           CASE WHEN (coalesce(CP.montant_base,                "0")  +
                      coalesce(CP.montant_bonus,               "0")  +
                      coalesce(CP.montant_incitation,          "0")) +
                      coalesce(CP.solde_ant_non_ou_trop_percu, "0")  +
                      coalesce(CP.regul_avenant,               "0")  < min
                THEN  0 
                ELSE  coalesce(ft.montant,0)
                END),"0")                                                            as total_payer,
     
           IF(ft.pourcentage = 1,(((coalesce(CP.montant_base,               0)  +
                                    coalesce(CP.montant_bonus,              0)  +
                                    coalesce(CP.montant_incitation,         0)) +
                                    coalesce(CP.solde_ant_non_ou_trop_percu,0)  +
                                    coalesce(CP.regul_avenant,0)) * 
           CASE WHEN (coalesce(CP.montant_base,                "0")  +
                      coalesce(CP.montant_bonus,               "0")  +
                      coalesce(CP.montant_incitation,          "0")) +
                      coalesce(CP.solde_ant_non_ou_trop_percu, "0")  +
                      coalesce(CP.regul_avenant,               "0")  < min 
                THEN  0 
                ELSE  coalesce(ft.montant,                      0) 
                END) / 100,
     
           CASE WHEN (coalesce(CP.montant_base,                "0")  +
                      coalesce(CP.montant_bonus,               "0")  +
                      coalesce(CP.montant_incitation,          "0")) +
                      coalesce(CP.solde_ant_non_ou_trop_percu, "0")  +
                      coalesce(CP.regul_avenant,               "0")  < min 
                THEN  0 
                ELSE  coalesce(ft.montant,                      0)
                END) as frais_retrait,
     
            coalesce(ft.min,                   0) as min,
            coalesce(ft.max,                   0) as max,
            coalesce(ft.id_frais_de_transfert, 0)
     
               FROM  coresponsabilite_paiement                as CP
     
         INNER JOIN  registre_activite                        as RA
                 ON  CP.id_registre_activite                  = RA.id_registre_activite 
     
         INNER JOIN  menage_valider                           as MV
                 ON  RA.id_menage_valider                     = MV.id_menage_valider
     
         INNER JOIN  menage_a_enqueter                        as ME
                 ON  MV.id_menage_enquete                     = ME.id_menage_enquete
     
         INNER JOIN  activite                                 as A
                 ON  RA.id_activite                           = A.id_activite
     
         INNER JOIN  menage                                   as M
                 ON  ME.id_menage                             = M.id_menage
     
         INNER JOIN  fokontany                                as F
                 ON  M.id_fokontany                           = F.id_fokontany
     
    LEFT OUTER JOIN  coresponsabilite_periode_paiement        as CPP
                 ON  CP.id_coresponsabilite_periode_paiement  = CPP.id_coresponsabilite_periode_paiement
     
    LEFT OUTER JOIN  presence_registre_semaine                as PGS
                 ON  RA.id_registre_activite                  = PGS.id_registre_activite
     
    LEFT OUTER JOIN  agence_paiement                          as AP
                 ON  CP.id_agence_paiement                    = AP.id_agence_paiement
     
    LEFT OUTER JOIN  frais_de_transfert                       as ft
                 ON  ft.id_agence_paiement                    = CP.id_agence_paiement
     
     
     
    '.$where.''.$periode.' AND (is_valid IS null OR is_valid = 1) AND is_rapprochement = 0';
     
    $reqB =  ''.$reqB.' GROUP BY CP.id_coresponsabilite_paiement, ft.id_frais_de_transfert HAVING total_ >= min AND total_ <= max
    	UNION '.$reqB.' GROUP BY CP.id_coresponsabilite_paiement, ft.id_frais_de_transfert HAVING total_ <  min  OR total_ >  max'
    Voici quelques remarques :

    1) pourquoi dans votre table "coresponsabilite_paiement" avez-vous utilisez le marqueur NULL, au lieu de mettre un zéro ?
    Ceci vous oblige ensuite dans votre requête à indiquer la valeur zéro lorsque le marqueur NULL a été utilisé : "coalesce(CP.montant_base, "0") as montant_base".

    2) ne savez-vous pas qu'un calcul ne se fait pas avec des chaînes de caractères mais avec des expressions numériques ?
    Donc ne mettez pas un zéro entre guillemet, mais simplement un zéro numérique quand vous faites ceci "coalesce(CP.montant_base, 0) as montant_base".
    (en rouge la modification que j'ai faite).

    3) pourquoi répétez-vous plusieurs fois le même calcul au niveau supérieur de votre requête ?
    Croyez-vous que cela d'une part pertient et d'autre part performant ?

    Je prends l'exemple suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (coalesce(CP.montant_base,       0)  +
     coalesce(CP.montant_bonus,      0)  +
     coalesce(CP.montant_incitation, 0)) as periode_a_payer,
    que je vois au moins huit fois dans votre requête.

    Descendez votre calcul au niveau du from, puisqu'il s'agit de la table "coresponsabilite_paiement", comme ci-après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FROM  coresponsabilite_paiement as CP
    Faites plutôt :
    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
    from (
        select          id_coresponsabilite_paiement,
                        id_registre_activite,
                        id_coresponsabilite_periode_paiement,
               coalesce(montant_paye,'')                       as montant_paye
                        id_agence_paiement,
                        is_valid,
                        regul_avenant,
               coalesce(solde_ant_non_ou_trop_percu,'')        as solde_ant_non_ou_trop_percu,
               coalesce(montant_base,                0)        as montant_base,
    	       coalesce(montant_bonus,               0)        as montant_bonus,
    	       coalesce(montant_incitation,          0)        as montant_incitation,
               coalesce(solde_ant_non_ou_trop_percu, 0)        as solde_ant_non_ou_trop_percu
               coalesce(regul_avenant,               0)        as regul_avenant,
     
               coalesce(montant_base,                0) +
    	       coalesce(montant_bonus,               0) +
    	       coalesce(montant_incitation,          0)       as periode_a_payer,
     
               coalesce(montant_base,                0) +
    	       coalesce(montant_bonus,               0) +
    	       coalesce(montant_incitation,          0) +
               coalesce(solde_ant_non_ou_trop_percu, 0) +
               coalesce(regul_avenant,               0)       as total_,
     
    from coresponsabilite_paiement
    ) as CP
    Ainsi vous simplifiez votre requête et vous allez gagner en lisibilité !
    Je n'ai pas tout mis. A vous de compléter avec ce qui manque.

    Dans la requête supérieure, il suffit de faire référence à "CP.periode_a_payer" et à "CP.total_" au lieu du calcul comme vous le faites !

    4) prenez l'habitude de préfixer toutes vos colonnes par l'alias de la table qui lui correspond.
    Et non de temps en temps, quand cela vous arrange.
    A quelle table appartiennent les colonnes : "is_valid", "is_rapprochement" ?

    5) dans une jointure, le symbole '=' n'est pas une égalité mais une affectation.
    Prenez l'habitude de mettre en premier la colonne de la jointure qui va recevoir la valeur d'une autre table.
    C'est pas grand chose à faire, et cela rend votre requête plus lisible.

    6) le union ne vous sert à rien ! Pourquoi ?
    Car une ligne appartient soit à l'intervalle [ min ; max ] ou soit elle n'appartient pas.
    De ce fait, ajouter ceci dans votre première requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select ...,
          case WHEN CP.total_ >= min AND total_ <= max THEN 'in' else 'out' end as col_test,
    Ainsi en testant la valeur col_test, vous saurez dans quel cas vous êtes.
    Et de plus, cela va vous faire gagner du temps, car vous n'aurez pas deux extractions à faire.

    7) vu que nous n'avons pas le descriptif des tables, on ne sait rien sur vos index.
    En principe, lorsqu'on utilise la clause "where", chaque colonne doit être associé à un index.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 16/09/2008, 18h24
  2. Exécution d'une requête SQL qui affiche un message
    Par Platon93 dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 29/11/2006, 17h15
  3. [MySQL] Requête SQL qui zappe la premiere ligne
    Par mulbek dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 19/01/2006, 17h24
  4. Réponses: 2
    Dernier message: 06/06/2005, 16h13
  5. Requête SQL qui me bloque
    Par David Guillouet dans le forum Langage SQL
    Réponses: 5
    Dernier message: 27/04/2004, 15h52

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