Exécution trop lente de requète [Résolu]

Messages postés
458
Date d'inscription
lundi 24 août 2009
Dernière intervention
8 décembre 2018
-
Bonjour,
ma page de cesse de tourner quand j'exécute ma requête .
il y a t il une autre méthode ??
                
$sql = "SELECT *
FROM victime V
,prejudicemoraux PM
,agent AG
,tb_departement DPTD
,tb_sous_prefecture SPD
,tb_commune COMD
,tb_localite LCD
,prejudicemateriel PMAT
,infogenerale IG
,tb_parent P
WHERE $critere
AND V.matricule = PM.id_prejM
AND PM.id_prejM = AG.id
AND AG.id = DPTD.id
AND DPTD.id = SPD.id
AND SPD.id = COMD.id
AND COMD.id = LCD.id
AND LCD.id = PMAT.id_prejMat
AND PMAT.id_prejMat = IG.id_infoG
AND IG.id_infoG = P.id
ORDER BY V.nomV
";
Afficher la suite 

Votre réponse

6 réponses

Messages postés
23600
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
13 décembre 2018
0
Merci
Bonjour,

Oui... en passant par des jointures INNER JOIN ou LEFT JOIN..
Et puis.. tout dépend aussi de ce que contient ta variable $criteres...

Par contre, es-tu sûr que le souci vienne de la requête ( tu l'as testé en direct dans ta BDD ?? ) ou de son traitement dans son code php ??

PS: Pourquoi.... alors que tu poses une question sur une REQUETE SQL ... tu poses ta question dans PHP ????
(ce n'est pas la première fois que je te fais cette remarque ! )





Commenter la réponse de jordane45
Messages postés
458
Date d'inscription
lundi 24 août 2009
Dernière intervention
8 décembre 2018
0
Merci
en direct exécution de la requête donne rien
jordane45
Messages postés
23600
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
13 décembre 2018
-
La requête à tester....est celle que tu récupères via un echo bien sûr. ...
Commenter la réponse de msi79
Messages postés
6711
Date d'inscription
mercredi 13 avril 2011
Dernière intervention
28 septembre 2015
0
Merci
Bonjour,

je connais ce genre de problème.....

D'une part, si la volumétrie de données est importante, il faut déja limiter le nombre de fiches. Donc faire un LIMIT, exemple:

LIMIT 0,20


à rajouter dans le code SQL va limiter à 20 fiches....


Ensuite, piège très grossier dans lequel beaucoup tombent, même des pros en BDD, c'est oublier d'indexe les champs sur lesquels on fait des WHERE.

Par exemple, dans votre code SQL, je vois ceci:

WHERE $critere  


Si un des critères est par exemple date_des_faits, il faut que ce champ soit indexé.

Enfin, je vois que vous utilisez des alias de noms de tables:

FROM victime V
,prejudicemoraux PM
,agent AG
,tb_departement DPTD
,tb_sous_prefecture SPD
,tb_commune COMD
,tb_localite LCD
,prejudicemateriel PMAT
,infogenerale IG
,tb_parent P


C'est très bien pour la lisibilité, mais il faudrait gérer les jointures entre ces tables avec INNER JOIN et les index primaires.

Attention, trop de jointures "flinguent" les performances, voire déconnectent des données.

Je serai à votre place, je ferai ceci:

SELECT *
            FROM victime V
WHERE $critere   
 ORDER BY V.nomV
LIMIT 0,20


afin de sortir 20 fiches respectant vos critères (champs indexés évidemment). Ensuite, vous affichez le minimum syndical à l'écran et ensuite, quand on veut voir une fiche, là vous allez piocher dans les différentes tables ce qui est nécessaire pour voir la fiche en détail.

Performance maximale assurée...

A+
Commenter la réponse de mpmp93
Messages postés
23600
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
13 décembre 2018
0
Merci
@mpm :

Indexer les champs : Oui (j'avais oublié de lui dire).

Utiliser les Jointures : Oui (je lui ai dit)

Utiliser des "LIMITES" .. mouais... pourquoi pas... Mais dans ce cas.. il est plus propre d'utiliser de la pagination... mais là.. c'est un autre sujet.

Ensuite, vous affichez le minimum syndical à l'écran et ensuite, quand on veut voir une fiche, là vous allez piocher dans les différentes tables ce qui est nécessaire pour voir la fiche en détail.
[...]
Performance maximale assurée...
Pas nécessairement... tout dépend de ce qu'il veut avoir à l'écran....et comment il l'affiche.
Si il découpe son affichage en plusieurs "vues" du genre :
Un tableau contenant le strict minimum ... puis si on clique sur la ligne d'un ticket.. on affiche les infos de se ticket (et donc.. seulement à ce moment là on va requêter la BDD pour en récupérer le contenu...) là.. oui.....
Mais connaissant MSI et sa façon de coder et la manière dont il présente le contenu de ses pages... à mon avis.. ça ne lui correspondra pas...


Sans oublier ...Pour gagner en performance.. il faut aussi limiter les SELECT * et ne faire un SELECT que des champs nécessaires...

Et enfin... tout dépend également de ce qu'il a dans son WHERE.
Si le WHERE contient des conditions sur des champs TEXTE (ou varchar).. la requête sera forcément plus longue que sur des champs numériques....

Bref...

Déjà... il faut, pour s'assurer que le souci vient de la requête, et non pas de son traitement lors de l'affichage des données dans la page PHP.. qu'il teste sa requête en direct dans la BDD ...
( 1 - Faire un ECHO de la requête dans la page PHP
2 - Prendre cette requête ainsi générée et la tester directement dans la BDD
3 - Regarder combien de temps elle met....)
=> Perso.. si elle met plus de 2 voir 3 secondes (et encore.. je suis large)... c'est clair que la lenteur vient d'elle.....
=> Sinon... le souci vient du traitement dans la page !
Commenter la réponse de jordane45
Messages postés
458
Date d'inscription
lundi 24 août 2009
Dernière intervention
8 décembre 2018
0
Merci
bonjour @mpmp93. merci de bien vouloir m'aider .
au fait au départ c'est ce que j'avais fait :
SELECT *
FROM victime V
WHERE $critere
ORDER BY V.nomV
LIMIT 0,20
mais il se trouve que quand je dois afficher par exemple la liste des blessés ou le critère se trouve dans une autre tables j'arrive pas .
mpmp93
Messages postés
6711
Date d'inscription
mercredi 13 avril 2011
Dernière intervention
28 septembre 2015
-
PS: si INNER JOIN marche pas, faites un LEFT JOIN

Blague: le JOIN ne se fume pas....
msi79
Messages postés
458
Date d'inscription
lundi 24 août 2009
Dernière intervention
8 décembre 2018
-
Comment transformer cette requète en utilisant INNER JOIN . Je maitrise pas cette methode
  $sql = "SELECT * 
FROM victime V
,prejudicemoraux PM
,agent AG
,tb_departement DPTD
,tb_sous_prefecture SPD
,tb_commune COMD
,tb_localite LCD
,prejudicemateriel PMAT
,infogenerale IG
,tb_parent P
WHERE $critere
AND V.matricule = PM.id_prejM
AND PM.id_prejM = AG.id
AND AG.id = DPTD.id
AND DPTD.id = SPD.id
AND SPD.id = COMD.id
AND COMD.id = LCD.id
AND LCD.id = PMAT.id_prejMat
AND PMAT.id_prejMat = IG.id_infoG
AND IG.id_infoG = P.id
ORDER BY V.nomV LIMIT 0,20
";
jordane45
Messages postés
23600
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
13 décembre 2018
-
Est ce que tu as cherché un minimum au moins ??
msi79
Messages postés
458
Date d'inscription
lundi 24 août 2009
Dernière intervention
8 décembre 2018
-
OUI J'AI TENTE CA MARCHE PAS JE CROIS QUE JE ME MÉLANGE VU QUE IL Y A TROP DE TABLES
mpmp93
Messages postés
6711
Date d'inscription
mercredi 13 avril 2011
Dernière intervention
28 septembre 2015
-
Il faut commencer par faire une jointure. A mon avis, ce serait suffisant.

Vous faites un SELECT *

ce qui signifie:
- affichetr TOUS les champs de toutes les tables. Si chaque table a 10 champs, vous affichez 100 champs par enregistrement. C'est improductif.

Vous faites une application orientée web. Il faut:
- une présélection avec une quantité de champs très limitée et un filtrage limité à quelques critères (date et/ou lieu et/ou intervenant....)
- un clic sur une fiche et vous récupérez les infos nécessaires pour cette fiche en plusieurs SELECT successifs.

Concernant les jointures, des cours en ligne, exemple:
http://www.areaprog.com/sql/cours-308-les-jointures-inner-join-left-right-et-full-outer-join

A+
Commenter la réponse de msi79
Messages postés
23600
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
13 décembre 2018
0
Merci
OUI J'AI TENTE CA MARCHE PAS JE CROIS QUE JE ME MÉLANGE VU QUE IL Y A TROP DE TABLES
Et tu penses que si tu ne nous montres pas ce que tu as essayé de faire que nous allons pouvoir t'aider à corriger ??

Nb : juste pour info :
Pour créer/tester ses requêtes...il faut le faire en direct dans la BDD (pas dans ta page PHP)....


Je te donne la première jointure :

SELECT * 
 FROM victime V
 LEFT JOIN prejudicemoraux PM ON  V.matricule  = PM.id_prejM



A toi de compléter...

NB² : Pense que L'ordre des Jointures dépend de la structure de ta table et des infos que tu souhaites avoir dans ta requête...donc commence par tester une première jointure... puis si elle te donne le résultat attendu..ajoute la secode..etc...


Avant de poser une question, merci de lire la charte du site.
Cordialement, Jordane
mpmp93
Messages postés
6711
Date d'inscription
mercredi 13 avril 2011
Dernière intervention
28 septembre 2015
-
Pour créer/tester ses requêtes...il faut le faire en direct dans la BDD (pas dans ta page PHP)....

Je rajouterai que "le faire en direct", c'est à dire via phpMyAdmin.... -> onglet SQL et saisir sa requête SQL à la main, puis cliquer sur "exécuter"
jordane45
Messages postés
23600
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
13 décembre 2018
-
Ou encore mieux... via des logiciels comme HeidiSQL...
http://codes-sources.commentcamarche.net/faq/10778-heidisql-tester-ses-requetes-sql
Commenter la réponse de jordane45

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.