Mysql : optimisation variable "key_buffer"

Cette page de 2009 reste d'actualitĂ© (au moins pour les tables MyISAM) et les remarques et conseils peuvent s'appliquer Ă  la variable "innodb_buffer_size" qui remplit Ă  peu prĂšs la mĂȘme fonction pour InnoDB.

Sur quelle information optimiser la valeur de ce paramĂštre ? 
Ce paramÚtre est réservé aux tables "MyIsam", de plus en plus rares au profit des tables InnoDB.

KEY_BUFFER = taille rĂ©servĂ©e au buffer des index. Sa taille doit ĂȘtre assez importante, l'idĂ©al est que tous les index rĂ©sident en mĂ©moire limitant ainsi les IO. 
Vous pouvez calculer cette taille en Ă©valuant la taille des index de votre base de donnĂ©es. L'utilisation de MySQL-Admin vous permet de suivre "en direct" l'Ă©volution de l'utilisation de ce cache. Voir dans la section "Health", onglet "Memory Health" de MySQL-Admin. La partie "Key efficiency" vous permet de voir la partie du buffer effectivement utilisĂ©e ainsi que le "hitrate". 
Le "hitrate" est le pourcentage de clĂ©s effectivement lues depuis le buffer. 
Attention : Ne pas tenir compte des valeurs présentes peu aprÚs un redémarrage, il faut attendre plusieurs heures que le fonctionnement de la base se stabilise et que l'utilisation corresponde à l'utilisation moyenne normale des applications liées à cette base.

INNODB_BUFFER_POOL_SIZE = taille rĂ©servĂ©e au buffer Innodb (data + index) 
Plus la valeur est Ă©levĂ©e, meilleur est le fonctionnement de la base ... La mĂ©moire Ă©tant bien moins rare qu'il y a quelques annĂ©es on peut mettre ce qu'il faut. 
Si on a assez de mémoire pour contenir la taille de la base ne pas hésiter, mais calculer au moins le volume des tables les plus accédées plus 20 ou 30%.

INNODB_BUFFER_POOL_INSTANCES = Nombre de "sous pools" 
Une valeur de 1 par Gigaoctet de POOL_SIZE est à considérer comme correcte, mais mettre une valeur proche de celle du nombre de coeurs de processeur est une option à ne pas négliger.

  • Des buffers trop petits --> hitrate bas et :
    •     temps de rĂ©ponse allongĂ©
    •     IO plus Ă©levĂ©es
  • Des buffers trop grands --> mĂ©moire gachĂ©e.

Il n'est pas la peine de mobiliser 8 Gigaoctets de mĂ©moire si seulement 50% sont utilisĂ©s, la mĂ©moire Ă©conomisĂ©e ici peut avec profit ĂȘtre utilisĂ©e ailleurs, c'est le cas de la plupart des paramĂštres de mĂ©moire, trop petits cela ralentit, trop grands cela utilise inutilement de la mĂ©moire. 
Si votre base est "petite" par rapport Ă  la mĂ©moire mettez ce qu'il faut, sur une machine spĂ©cialisĂ©e "base de donnĂ©es" 75/80% de la mĂ©moire est parfait pour InnoDB. 
Toutefois si l'ensemble de vos tables ne "pÚse" que 30 Go il est inutile de réserver 64 Go de mémoire !

TABLE_OPEN_CACHE = nombre de tables en cache. 
Une cette valeur Ă©gale au nombre de tables si cela est possible. Note : on trouve un tas de choses Ă  ce sujet ... 
Une taille peu différente du nombre de tables de la base semble en général favorable.

Un autre point Ă  surveiller est la mĂ©moire affectĂ©e aux tris et autres zones temporaires (TMP_TABLE_SIZE et MAX_HEAP_TABLE_SIZE). Si certaines requĂȘtes ramĂšnent beaucoup de lignes Ă  trier cela nĂ©cessite de la place et, lĂ  aussi, affecter un peu de mĂ©moire n'est pas un luxe. En gĂ©nĂ©ral 64 Ă  320Mo sont suffisants, surveiller le pourcentage de tables temporaires sur disque. La valeur de READ_IO_THREADS et WRITE_IO_THREADS peut ĂȘtre au minimum de 2, mais sur une machine multiprocesseurs aller presque jusqu'au nombre de coeurs est une bonne pratique ... 
La taille des READ, SORT et JOIN BUFFER_SIZE est à suivre et des valeurs de 2 à 16M sont en général adaptées.

Mais il faut aussi penser Ă  l'activitĂ© de crĂ©ation/modification de la base et affecter un minimum de mĂ©moire au INNO_DB_LOG_BUFFER_SIZE afin de fluidifier les Ă©critures sur le log. 
A propos de accĂšs disques, plus ils sont rapides, mieux c'est. L'utilisation de SSD permet d'atteindre des vitesses impressionnantes et la mise en RAID 1 permet d'augmenter encore ce type de performance avec toutefois un certain risque, le RAID 10 est parfait. Voir ici l'influence de la variable INNODB_IO_CAPACITY qui permet Ă  la base d'optimiser son fonctionnement en fonction de la vitesse des I/O, en gĂ©nĂ©ral de 100 Ă  1000 pour des disques standard et > 10000 pour des SSD. 
Sur des systĂšmes largement multi-processeurs on peut aussi jouer sur les paramĂštres INNODB_READ_IO_THREADS et INNODB_WRITE_IO_THREADS et les augmenter Ă  2,3 ... afin d'accĂ©lĂ©rer au maximum les IO, base en lecture --> forcer le nombre de READ_IO_THREADS, si beaucoup d'Ă©critures forcer le nombre de WRITE_IO_THREADS. Toutefois si vous n'avez pas de SSD ou de multiples disque de donnĂ©es cela peut ĂȘtre trĂšs peu efficace. 
Pour l'ajustement de ces valeurs suivre l'Ă©volution des compteurs et ratios fournis par un systĂšme de suivi de performance tel que Shinken + Graphite/InfluxDB ou d'autres produits non libres, Mysql Workbench fournit aussi l'accĂšs Ă  beaucoup d'informations utiles.