web-dev-qa-db-fra.com

Règle générale pour les propriétés MySQL tmp_table_size et max_heap_table_size

Le titre résume à peu près la question elle-même: existe-t-il une règle empirique concernant les valeurs de tmp_table_size et max_heap_table_size Propriétés MySQL?

J'ai eu une sérieuse dégradation des performances qui était due au fait que MySQL utilisait de l'espace disque pour trier des fichiers un résultat JOIN.

En augmentant tmp_table_size et max_heap_table_size to 3G a résolu le problème, mais il s'agit davantage d'une approche par essais et erreurs.

Existe-t-il un moyen plus solide de calculer une valeur appropriée pour ces deux?

4
Niko

Je recommande un simple 1% de mémoire pour chacun d'eux.

  • max_heap_table_size Est la limite d'une table ENGINE=MEMORY Que vous CREATE. Peu de gens utilisent ce moteur, si vous le faites, définissez la taille maximale juste avant de créer.

  • LEAST(max_heap_table_size, tmp_table_size) est le plafond sur la taille de certaines tables temporaires implicites à obtenir. Ce sont des tables utilisées dans SELECTs (etc) pour gérer GROUP BY, ORDER BY, Des sous-requêtes, etc.

Étant donné que ces tables temporaires peuvent être créées par chaque connexion, et éventuellement plusieurs tables temporaires par requête, 1% de RAM est une limite plutôt "sûre". Lorsque MySQL manque de RAM, le système d'exploitation échange choses - L'échange de MySQL est terrible pour les performances.

De plus, si vous les définissez trop grands, vous dérobez RAM à d'autres utilisations (par exemple, buffer_pool), ce qui pourrait ralentir potentiellement toutes les requêtes.

Autre Règles générales

Voir aussi SQL_BIG_RESULT.

4
Rick James

Il peut être tentant d'augmenter tmp_table_size (et sa dépendance, max_heap_table_size IF MEMORY est utilisé pour les moteurs de mémoire temporaires - les dernières versions utilisent InnoDB à la place) aussi longtemps que possible. Après tout, si vous exécutez la même requête avec une taille de table plus grande, ce sera probablement plus rapide!

Cependant, il y a 2 raisons de ne pas le faire, auxquelles je peux penser:

  • Si la table temporaire va être énorme, vous allez perdre du temps à insérer des lignes dans la mémoire, puis à la copier sur le disque, puis à continuer d'insérer des lignes. Selon la requête, vous pouvez constater que l'écriture sur le disque dès que possible peut être plus rapide.
  • Bien que la configuration de grands tampons puisse sembler une bonne idée, il n'y a pas de mémoire infinie - donc si chaque requête/connexion va prendre 3 Go de mémoire, vous pouvez en manquer et commencer à écrire sur le disque de toute façon en raison de l'échange de mémoire virtuelle (qui finira probablement par planter MySQL en raison d'erreurs de mémoire insuffisante ou sera incroyablement lent).

Maintenant, si vous exécutez simplement une seule requête et non plusieurs en concordance (vous n'aurez donc pas ces problèmes), et que cela fonctionne pour vous d'être beaucoup plus rapide, n'hésitez pas à l'augmenter (mais vous voudrez probablement le changer pour la session uniquement afin qu'elle n'affecte pas les autres requêtes qui pourraient obtenir les régressions que j'ai mentionnées).

Pour calculer une bonne valeur, choisissez la quantité maximale de mémoire que vous souhaitez que votre requête prenne (notez que vous aurez également besoin de mémoire pour le join_buffer_size. sort_buffer_size, read_buffer_size, et autres tampons) ou la plus grande table temporaire que vous généreriez, quelle qu'elle soit.

Vous pouvez utiliser le Created_tmp_disk_tables et Created_tmp_tables variables pour savoir combien de tables temporaires et de tables temporaires sur le disque vous créez à portée globale (bien que certaines soient inévitables - par exemple, les tables de tas n'autorisent pas les blobs, et certaines requêtes auront toujours besoin de tables temporaires, quelle que soit l'indexation) ).

2
jynus