optimisation requête mysql - SQL/NoSQL - Programmation
Marsh Posté le 01-04-2015 à 15:46:05
Utilise EXPLAIN dans phpMyAdmin pour voir ce qui bloque :
EXPLAIN SELECT.... FROM...
Après, le OR et le like, ça te tue les perfs. En général, avec LIKE, impossible d'utiliser un index. Déjà, pour virer les OR, tu peux faire ça :
'SELECT...FROM...WHERE CONCAT(m.nom_modele, nom_produit, p.ref_produit) LIKE "%'.$mot_cle.'%"';
Marsh Posté le 01-04-2015 à 16:43:46
Merci pour l'astuce je ne connaissais pas !
Mais cette dernière requête mets 2s justement, c'est la 1ère en haut qui met 20s !
Marsh Posté le 01-04-2015 à 16:50:59
p.id_modele, m.id_modele, ma.id_marque, m.id_marque, c.id_cat, p.id_cat sont tous déclarés clé primaire ou clé étrangère (suivant le cas) ?
Ca donne quoi explain ?
Parce que je suis étonné des perfs : mon appli Astres a une requête sur les tickets qui fait des LEFT JOIN sur bien 6-7 tables dont une fait plus de 30000 enregistrements et ça met pas 20s. Ton appli tourne sur quel matos ? Moi, c'est un CPU 2.5 Ghz double coeur, 2 Go de ram.
Tu peux aussi tuner le fichier de conf de Mysql pour augmenter la taille de certains caches, buffers, nb de tables temporaires ouvertes en même temps ou taille des tables temporaires en mémoire ou sur le hdd...
Marsh Posté le 01-04-2015 à 23:37:39
toutes déclarées en primaire dans leur tables respectives, pas de clé étrangères car MySam
Voilà le explain
EXPLAIN SELECT p.id_produit, p.nom_produit, p.id_modele, p.description_produit, p.ref_produit, p.id_cat, p.stock_produit, p.actif, p.new, p.prix_vente_produit, p.prix_promo, p.coupdecoeur, m.id_modele, m.nom_modele, m.id_marque, ma.nom_marque, ma.id_marque, c.nom_cat
FROM tb_produits p
LEFT JOIN tb_modeles m ON p.id_modele = m.id_modele
LEFT JOIN tb_marques ma ON ma.id_marque = m.id_marque
LEFT JOIN tb_cat c ON c.id_cat = p.id_cat
ORDER BY id_produit
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE p ALL NULL NULL NULL NULL 20321 Using filesort
1 SIMPLE m eq_ref PRIMARY PRIMARY 4 transforbike.p.id_modele 1
1 SIMPLE ma eq_ref PRIMARY PRIMARY 4 transforbike.m.id_marque 1
1 SIMPLE c eq_ref PRIMARY PRIMARY 4 transforbike.p.id_cat 1
J'ai juste fait un coup de mysqltuner pour le my.conf
3Go de mémoire, CPU 2Ghz
Sur quoi dois-je faire les index ?
Marsh Posté le 02-04-2015 à 00:06:21
c'est résolu
Le pb vient de mon php car je calcule le nombre total de réponse sur la même requête, je la fais donc 2 fois
J'ai aussi ajouté un mysql_free_result avant de faire la vrai requête
merci !
Marsh Posté le 02-04-2015 à 10:17:28
Pour les clés étrangères, mets un index sur ces champs.
Marsh Posté le 02-04-2015 à 14:05:41
Merci
Et faire ça
Code :
|
Puis ça
Code :
|
c'est mauvais ?
Marsh Posté le 02-04-2015 à 14:27:34
Dans l'absolut, non ce n'est pas mauvais mais si tu ne fait aucune action en php sur tes tableaux (changement de tri, filtre ou autre), tu peux utiliser directement ton retour sql pour l'affichage...
Le plus couteux (hormis le poids de tes différents tableaux en mémoire) c'est sans doute ton :
Code :
|
Soit tu fait
Code :
|
Ou alors
Code :
|
Personnellement j'ai tendance à faire :
Code :
|
Marsh Posté le 02-04-2015 à 14:58:49
Pareil, pour la récup de données provenant d'une BD, je fais un while. Ca évite de passer par un tableau intermédiaire qui peut être consommateur de mémoire.
Marsh Posté le 02-04-2015 à 15:02:10
Merci les gars c'est sympa
Et pour la pagination ?
Vous faîtes un mysql_num_row sur une requête simplifiée et vous ajoutez le limit en conséquence ?
Marsh Posté le 02-04-2015 à 15:04:32
Moi, je fais un COUNT() sur une requête simplifiée puis la vrai requête pour avoir les enregistrements à afficher.
Marsh Posté le 01-04-2015 à 15:33:17
Bonjour
Ma requête sur 20000 enregistrements prends 20s
Je stocke les résultats dans un tableau php et ajoute une pagination mais je n'ai pas l'impression que ça vienne de la
Je pense plus tôt que c'est une question d'index mais je sèche , j'ai essayé qq trucs mais sans résultats
D'ailleurs la requête suivante est rapide
Merci à ceux qui prendront le temps de me répondre