Aide à l'optimisation de requête

Aide à l'optimisation de requête - SQL/NoSQL - Programmation

Marsh Posté le 14-04-2011 à 11:23:17    

Bonjour à tous,
Mon site devient TRES lent.
J'ai mis en place le log slow queries de mysql et me rends compte que certains requêtes font 160000 recherches/accès.
Il doit sans doute y avoir moyen d'améliorer cela.
n'ayant pas vraiment les connaissances adéquates, je recherche de l'aide.  :sweat:  
 
Quelqu'un peut il m'aider? :hello:


Message édité par brash le 14-04-2011 à 11:39:47
Reply

Marsh Posté le 14-04-2011 à 11:23:17   

Reply

Marsh Posté le 14-04-2011 à 11:30:32    

Sans les requêtes qui posent problème on ne peut pas faire grand chose.

 

La première chose à faire serait d'examiner le plan d'exécution de ces requêtes, et de vérifier s'il ne manque pas des indexes...

 


...et sinon c'est un soucis SQL, pas PHP.


Message édité par skeye le 14-04-2011 à 11:30:47

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 14-04-2011 à 11:35:06    

tu peux regarder aussi pour tuner mysql : http://mysqltuner.pl/mysqltuner.pl
 
Ca te dira les variables à améliorer... En augmentant la taille de certains caches, ça peu faire des miracles parfois ;)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 14-04-2011 à 11:41:40    

C'est modifié! Désolé.
C'est déjà sympathique de me répondre :D
 
Voici quelques requêtes, ce sont celles qui ont générés le plus d'accès et pris le plus de temps
 
# Time: 110412  1:33:22
# User@Host: XXXX[XXXX] @ localhost [127.0.0.1]
# Query_time: 8  Lock_time: 0  Rows_sent: 1  Rows_examined: 171080
select count(distinct p.products_id) as total  from products p left join manufacturers m using(manufacturers_id) left join specials s on p.products_id = s.products_id, products_description2 pd, categories c, products_to_categories p2c where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '1' and p.products_id = p2c.products_id and p2c.categories_id = c.categories_id  and ((pd.products_name like '%baquet%' or p.products_model like '%baquet%' or m.manufacturers_name like '%baquet%') );
 
 
 
# Time: 110412  1:56:26
# User@Host: XXX[XXXX] @ localhost [127.0.0.1]
# Query_time: 10  Lock_time: 0  Rows_sent: 10  Rows_examined: 134179
select p.products_id, pd.products_name, p.products_image, p.products_price, p.products_tax_class_id, p.products_date_added, m.manufacturers_name from products p left join manufacturers m on (p.manufacturers_id = m.manufacturers_id), products_description2 pd where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '1' order by p.products_date_added DESC, pd.products_name limit 0, 10;
 
 
# Time: 110412  2:10:58
# User@Host: XXX[XXXX] @ localhost [127.0.0.1]
# Query_time: 7  Lock_time: 0  Rows_sent: 1  Rows_examined: 171080
select count(distinct p.products_id) as total  from products p left join manufacturers m using(manufacturers_id) left join specials s on p.products_id = s.products_id, products_description2 pd, categories c, products_to_categories p2c where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '1' and p.products_id = p2c.products_id and p2c.categories_id = c.categories_id  and ((pd.products_name like '%black%' or p.products_model like '%black%' or m.manufacturers_name like '%black%') and (pd.products_name like '%led%' or p.products_model like '%led%' or m.manufacturers_name like '%led%') and (pd.products_name like '%strap%' or p.products_model like '%strap%' or m.manufacturers_name like '%strap%') );

Message cité 1 fois
Message édité par brash le 14-04-2011 à 11:47:24
Reply

Marsh Posté le 14-04-2011 à 11:48:12    

Comment fonctionne mysqltuner.pl ?

Reply

Marsh Posté le 14-04-2011 à 11:49:31    

- vire les "distinct" et met dans tes requêtes des group by
- ce sont tes like + or qui ralentissent (index pas utilisés) : préfère les match...against


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 14-04-2011 à 11:50:18    

brash a écrit :

Comment fonctionne mysqltuner.pl ?


 
c'est un script en perl. T'installe perl puis tu exécutes le script donné en url. T'obtient une sortie texte avec des indications de quoi faire.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 14-04-2011 à 11:53:03    

brash a écrit :

Code :
  1. SELECT count(DISTINCT p.products_id) AS total  
  2. FROM products p
  3.        LEFT JOIN manufacturers m USING(manufacturers_id)
  4.        LEFT JOIN specials s ON p.products_id = s.products_id,
  5.        products_description2 pd,
  6.        categories c,
  7.        products_to_categories p2c
  8. WHERE p.products_status = '1'
  9. AND p.products_id = pd.products_id
  10. AND pd.language_id = '1'
  11. AND p.products_id = p2c.products_id
  12. AND p2c.categories_id = c.categories_id  
  13. AND ((pd.products_name LIKE '%baquet%' OR p.products_model LIKE '%baquet%' OR m.manufacturers_name LIKE '%baquet%') )



 
C'est moi ou tu fais tes jointures un peu n'importe-comment, un coup dans la clause FROM, un coup dans la clause WHERE?[:autobot]
Je suis pas sûr que ça aide vachement le plan d'exécution, ça - je commencerais déjà par écrire ça comme ça, ne serait-ce que pour clarifier :
 

Code :
  1. SELECT count(DISTINCT p.products_id) AS total  
  2. FROM products p
  3.        LEFT JOIN manufacturers m USING(manufacturers_id)
  4.        LEFT JOIN specials s ON p.products_id = s.products_id,
  5.        JOIN products_description2 pd ON p.products_id = pd.products_id AND AND pd.language_id = '1' ,
  6.        JOIN products_to_categories p2c ON p.products_id = p2c.products_id ,
  7.        JOIN categories c ON p2c.categories_id = c.categories_id
  8. WHERE p.products_status = '1'
  9. AND ((pd.products_name LIKE '%baquet%' OR p.products_model LIKE '%baquet%' OR m.manufacturers_name LIKE '%baquet%') )


 
Ensuite tu as une jointure sur categories, et pire une jointure gauche sur specials, mais je ne vois pas à quoi elles servent? Tu n'utilises le contenu de ces tables nulle part dans cette requête.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 14-04-2011 à 12:17:23    

J'ai placé le mysqltuner sur mon site.
J'y ai accédé par son url
ça me propose de le télécharger, je l'ouvre et j'ai le code, rien de plus :/

Reply

Marsh Posté le 14-04-2011 à 13:47:30    

le site, c'est le script pl. Tu le copies/colles dans un fichier txt et le fait exécuter ensuite par l'interpréteur de perl.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 14-04-2011 à 13:47:30   

Reply

Marsh Posté le 14-04-2011 à 18:01:37    

Bonjour, dans mon fichier advanced search j'ai peut être trouvé cette requête.  
 
 
J'ai trouve deux from séparés, et les ai remis en un.
 
J'obtiens donc ceci:
 
 
  $from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m using(manufacturers_id) left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id" join " . TABLE_PRODUCTS_DESCRIPTIONS2 . " pd on p.products_id = pd.products_id and pd.language_id = '1' join " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c on p.products_id = p2c.products_id join " . TABLE_CATEGORIES . " c on p2c.categories_id = c.categories_id;
 
 
Et le second from a été mis en commentaire.
 
Ca ne fonctionne pas. Une idée?

Reply

Marsh Posté le 14-04-2011 à 18:07:55    

ok j'ai corrigé moi même :D
J'ai donc cette ligne:
 
  $from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m using(manufacturers_id) left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id join " . TABLE_PRODUCTS_DESCRIPTION . " pd on p.products_id = pd.products_id and pd.language_id = '1' join " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c on p.products_id = p2c.products_id join " . TABLE_CATEGORIES . " c on p2c.categories_id = c.categories_id";
 
 
Et celle-ci mise en commentaire:
//  $from_str .= ", " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_CATEGORIES . " c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";
 
 
Ca vous semble cohérent? Comment voir si la requête est à présent plus adéquate?

Reply

Marsh Posté le 15-04-2011 à 10:09:12    

pour les équi-jointures, traditionnellement, on met plutôt inner join ;)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 15-04-2011 à 14:36:31    

Bonjour,
Peux tu m'indiquer dans la requête que j'ai mis hier soir, quelles sont les améliorations à apporter? Merci.

Reply

Marsh Posté le 15-04-2011 à 14:56:12    

Essaye de nous afficher la requête complète, et pas des bouts de code php...ce sera plus facile d'en faire quelque chose.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 15-04-2011 à 15:55:05    

Comment puis je voir la requête complète?
 
J'ai eu déjà énormément de mal à la modifier dans le code PHP.  Je ne sais pas comment l'afficher en version "normale" sql. Peux tu m'en dire plus? Merci

Reply

Marsh Posté le 15-04-2011 à 16:50:03    

en l'affichant dans ton code php...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 15-04-2011 à 16:53:18    

Je ne saisis pas.
 
Pour l'instant j'ai modifié la requête en éditant directement le fichier php avec notepad.
 
Cela m'affiche ma requête comme copié plus haut.
 
Comment peut on voir les requêtes d'un fichier php, sans tout le php autour?

Reply

Marsh Posté le 15-04-2011 à 16:54:38    

visiblement ton php construit la requête sous forme de chaine de caractère...fais afficher cette chaine avant d'exécuter la requête...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 15-04-2011 à 16:57:19    

Il faut vraiment m'excuser mais je débute...  Je suis débrouillard, je comprends tes paroles mais je ne sais pas comment faire afficher cela :/

Reply

Marsh Posté le 15-04-2011 à 16:58:18    

echo $mavariableaveclarequetededans; [:doc petrus]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 15-04-2011 à 17:17:34    

je vais essayer ça :D

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed