Optimiser requête lourde (Copying to tmp table ?)

Optimiser requête lourde (Copying to tmp table ?) - SQL/NoSQL - Programmation

Marsh Posté le 19-09-2011 à 18:32:15    

Hello à vous :)
 
je suis en ce moment en train de concevoir un outil permettant de générer un tableau de statistiques assez malléable, avec une requête MySQL qui s'adapte en fonction des besoins de l'utilisateur.
 
La masse de données dans la base est conséquente (comprendre des tables de plusieurs millions de lignes) et en constante expansion. Aussi, je me suis très vite heurté à des problèmes de performances assez drastiques.
 
Notez qu'il s'agit d'une requête avec plusieurs left / inner join, avec un group by sur deux champs pas nécessairement de la même table, et un order by également sur deux champs pas nécessairement dans la même table.
 
Donc, j'ai commencé par améliorer mes index, créer des index doubles là où c'était nécessaire / utile... Pas concluant. Optimisation des données de my.cnf à l'aide de tuning primer... je mets les données telles qu'elles sont après optimisation :
 
 

Code :
  1. [mysqld]
  2. character-set-server            = latin1
  3. init-connect                        ='SET NAMES  latin1'
  4. default-character-set           = latin1
  5. user                                            = mysql
  6. port                                            = 3306
  7. socket                                          = /var/run/mysqld/mysqld.sock
  8. pid-file                                        = /var/run/mysqld/mysqld.pid
  9. log-error                                       = /var/log/mysql/mysqld.err
  10. basedir                                         = /usr
  11. datadir                                         = /var/lib/mysql
  12. skip-locking
  13. key_buffer                                      = 128M
  14. max_allowed_packet                      = 16M
  15. table_cache                             = 512
  16. sort_buffer_size                        = 8M
  17. net_buffer_length                       = 8K
  18. read_buffer_size                        = 1M
  19. read_rnd_buffer_size            = 512K
  20. myisam_sort_buffer_size         = 8M
  21. language                                        = /usr/share/mysql/english
  22. query_cache_size                = 64M
  23. query_cache_limit               = 1M
  24. max_connections                 = 50
  25. join_buffer_size                = 1M
  26. thread_cache_size               = 64
  27. tmp_table_size                  = 64M
  28. max_heap_table_size             = 64M


 
 
Le fait est que ça ne réduit pas. En observant, on se rend compte que la requête reste longtemps en statut "Copying to tmp table". Je suppose que c'est le fait d'écrire la requête sur le DD, non ?
 
Quoi qu'il en soit, existe-t-il un moyen de se débarrasser de cette étape ? En augmentant un cache, ou autre...
 
Merci !


---------------
Si ça n'explose pas, vous ne faites pas avancer la science.
Reply

Marsh Posté le 19-09-2011 à 18:32:15   

Reply

Marsh Posté le 20-09-2011 à 08:43:31    

Si la requête n'est pas optimisable directement car trop lourdingue, il faut aussi tester en la scindant en requêtes + élémentaires qui iront beaucoup plus vite si l'on s'arrange bien. Faut pas toujours vouloir tout faire d'un seul bloc, car travailler sur X tables différentes à un coût, surtout avec des tris lourds au cul. T'as création d'une ou plusieurs tables temporaires car la base ne peut pas tout faire d'un seul coup et t'as des tris compliqués, elle scinde les opérations du mieux qu'elle peut. On évite autant que possible le recours aux tables temporaires, mais bon parfois on n'a pas vraiment le choix...


Message édité par rosco le 20-09-2011 à 08:45:06
Reply

Marsh Posté le 20-09-2011 à 10:07:15    

Tu peux monter tmp_table_size à 160 Mo et join_buffer_size à 16Mo pour voir...


---------------
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 20-09-2011 à 10:09:35    

Si ce genre de requete deviens trop lourde tu peux aussi precalculer un maximum de choses, faire des tables avec des valeurs precalculée et déja jointes.

Reply

Marsh Posté le 20-09-2011 à 10:19:32    

Hello,
 
il n'est malheureusement pas possible d'exploser la requête en plusieurs petites : c'est pas utile vu le contexte des tables. De plus, j'ai déjà un cron qui fait un max de choses la nuit pour préparer le terrain.
 
J'essaierai d'augmenter les valeurs comme le conseille rufo.
 
En attendant, j'ai réussi à résoudre une bonne partie du problème en installant un index triple. Si jamais au fur et à mesure que les données rentrent je rencontre de nouvelles difficultés, j'en reparlerai de nouveau ici.
 
Merci à vous ;)


---------------
Si ça n'explose pas, vous ne faites pas avancer la science.
Reply

Sujets relatifs:

Leave a Replay

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