Pourquoi MySQL crée-t-il autant de tables temporaires sur le disque?

13

Une erreur de configuration peut-elle conduire à créer trop de tables temporaires par les shows du tuner mysql..mysql

Current max_heap_table_size = 200 M
Current tmp_table_size = 200 M
Of 17158 temp tables, 30% were created on disk

table_open_cache = 125 tables
table_definition_cache = 256 tables
You have a total of 97 tables
You have 125 open tables.
Current table_cache hit rate is 3%

La table temporaire précédente était "sur les 23725 tables temporaires, 38% ont été créées sur le disque", mais j'ai changé max_heap et tmp_table à 200 m au lieu de 16 m et il a baissé à 30%.

Configuration:

engine myisam 
group_concat_max_len = 32768
key_buffer_size = 3.7 GB,
thread_stack = 256k,
table_cache = 125
query_cache_limit = 1M
query_cache_size = 16M
join_buffer_size = 2.00 M
max_connections = 800

Un autre système avec une configuration par défaut affiche "sur 23725 tables temporaires, 1% ont été créées sur le disque" avec la même base de données.

J'ai essayé de changer par défaut sur la machine avec ce problème et il affiche toujours "Sur 580 tables temporaires, 16% ont été créées sur le disque".

J'utilise Ubuntu 11.4 64 bits avec 48 Go de RAM. Quelqu'un peut-il proposer une solution?

Est-ce que changer le moteur de base de données de "myisam" en "mémoire" sur les tables utilisant "group by" corrigera ce problème? Comme expliqué ici: http://www.mysqlperformanceblog.com/2007/08/16/how-much-overhead-is-caused-by-on-disk-temporary-tables/

ananthan.nair
la source

Réponses:

16

mysqltuner fournit rarement des informations utiles. Il utilise principalement des statistiques non pertinentes sur les «taux de réussite» et impose des limites arbitraires à ce qui est un nombre acceptable de widgets acceptables. Si vous n'êtes pas confronté à un problème de performances, vous n'avez en fait pas besoin de résoudre l'un des problèmes qu'il vous présente. Cela étant dit, voici quelques informations générales sur les tables temporaires ...

MySQL utilise en interne le moteur de stockage MEMORY pour créer des tables temporaires implicites. Les tables temporaires sur disque utilisent le moteur de stockage MyISAM.

Des tables temporaires sont créées sur disque lorsque:

  • Les champs TEXT ou BLOB sont présents (car MEMORY ne prend pas en charge ces types)
  • la taille de la table temporaire implicite résultante dépasse le moindre de tmp_table_sizeoumax_heap_table_size
  • Si une colonne de plus de 512 octets est utilisée avec un GROUP BY ou UNION ou ORDER BY

Lisez la documentation MySQL sur les tables temporaires internes pour plus de détails.

Que pouvez-vous y faire? En supposant qu'il représente en fait un problème de performances (plutôt que de simplement vous déranger intellectuellement):

  • Évitez les champs TEXT / BLOB et utilisez plutôt les champs VARCHAR ou CHAR de taille appropriée dans la mesure du possible.
  • Si TEXT / BLOB sont inévitables, séquestrez-les dans des tables séparées avec une relation de clé étrangère et JOIGNEZ uniquement lorsque vous en avez besoin.
  • Traitez les grandes colonnes, plus de 512 octets comme vous le feriez pour les champs TEXT / BLOB mentionnés ci-dessus.
  • Assurez-vous que vos requêtes renvoient uniquement l'ensemble de résultats dont vous avez besoin (clauses WHERE sélectivement appropriées, évitez SELECT *)
  • Évitez les sous-requêtes et remplacez-les par des jointures, surtout si elles renvoient un ensemble de résultats volumineux
  • Dernier recours - augmentez les deux tmp_table_sizeet max_heap_table_size. Ne faites cela que si vous constatez que vos requêtes ne peuvent pas être optimisées.

Si vous êtes préoccupé par votre configuration MySQL et que vous n'êtes pas à l'aise avec les paramètres disponibles vous-même, vous pouvez utiliser l' assistant de configuration Percona comme point de départ.

Est-ce que changer le moteur de base de données de "myisam" en "memory" sur les tables utilisant "group by" corrigera ce problème? comme expliqué ici

Non, ce ne sera pas le cas et cela fera en sorte que vos tables ne seront jamais conservées sur le disque. Ne fais pas ça.

Aaron Brown
la source
+1, mais a ajouté que c'est le moindre de tmp_table_sizeoumax_heap_table_size
Derek Downey
La meilleure recommandation de mysqltuner était d'activer le journal des requêtes lentes. Il vous aidera à identifier les requêtes lentes, le cas échéant.
fat_mike
2

"utiliser temporaire" et "utiliser filesort" ne sont pas la fin du monde!

SELECT ... GROUP BY a, b ORDER BY c, d - Nécessite 1 ou 2 "tables temporaires".

Il y a des moments où vos requêtes utilisent des tables temporaires. Les tables temporaires peuvent ralentir une requête d'un petit facteur. Mais si la requête est toujours "assez rapide", ne vous en faites pas.

Si la requête est trop lente (avec ou sans tables tmp), discutons-en. Veuillez fournir SHOW CREATE TABLE, SHOW TABLE STATUS et EXPLAIN.

Rick James
la source
1
Si vous avez un index (a, b, c, d), il n'y aura pas de table temporaire.
Yvan