web-dev-qa-db-fra.com

Comment déterminer la taille optimale de sort_buffer_size?

J'ai lu un exemple de fichier de configuration qui dit ce qui suit:

# Sort buffer is used to perform sorts for some ORDER BY and GROUP BY
# queries. If sorted data does not fit into the sort buffer, a disk
# based merge sort is used instead - See the "Sort_merge_passes"
# status variable. Allocated per thread if sort is needed.

J'ai quelques requêtes qui utilisent filesort. Comment déterminer la taille de la mémoire tampon dont j'ai besoin pour que les requêtes s'exécutent correctement sans toucher le disque?

10

Il n'y a qu'une seule variable d'état qui se soucie de sort_buffer_size . C'est ce que vous avez dans le message de retour dans la question: Sort_merge_passes . La documentation MySQL dit:

Sort_merge_passes: nombre de passes de fusion que l'algorithme de tri a dû effectuer. Si cette valeur est grande, vous devriez envisager d'augmenter la valeur de la variable système sort_buffer_size .

Veuillez garder à l'esprit une chose à propos de sort_buffer_size

Si vous voyez plusieurs Sort_merge_passes par seconde dans la sortie SHOW GLOBAL STATUS, vous pouvez envisager d'augmenter la valeur sort_buffer_size pour accélérer les opérations ORDER BY ou GROUP BY qui ne peuvent pas être améliorées avec l'optimisation de requête ou l'indexation améliorée

Tout en élevant sort_buffer_size peut aider les requêtes avec GROUP BYle sable ORDER BYs, vous feriez mieux d'améliorer les requêtes que vous pouvez améliorer et d'ajouter des index pouvant être utilisés par l'Optimiseur de requête.

La question demeure: Comment vérifiez-vous les Sort_merge_passes ???

Utilisez ce code pour vérifier combien de Sort_merge_passes se sont produits au cours des 5 dernières minutes. Il calcule également les Sort_merge_passes par heure.

SET @SleepTime = 300;
SELECT variable_value INTO @SMP1
FROM information_schema.global_status WHERE variable_name = 'Sort_merge_passes';
SELECT SLEEP(@SleepTime) INTO @x;
SELECT variable_value INTO @SMP2
FROM information_schema.global_status WHERE variable_name = 'Sort_merge_passes';
SET @SMP = @SMP2 - @SMP1;
SET @SMP_RATE = @SMP * 3600 / @SleepTime;
SELECT @SMP,@SMP_RATE;

Si vous trouvez les Sort_merge_passes et le taux trop élevés, alors n'hésitez pas à augmenter sort_buffer_size . Supposons que vous souhaitiez augmenter à 4M. Vous exécuteriez ceci:

mysql> SET GLOBAL sort_buffer_size = 1024 * 1024 * 4;

Vous ajouteriez ensuite ceci à my.cnf

[mysqld]
sort_buffer_size = 4M

Vous devez exécuter le code périodiquement pour vérifier les autres moments Sort_merge_passes pics.

14
RolandoMySQLDBA

Les instructions du manuel (5.0-5.5) sont

Si vous voyez plusieurs Sort_merge_passes par seconde dans la sortie SHOW GLOBAL STATUS, vous pouvez envisager d'augmenter la valeur sort_buffer_size pour accélérer les opérations ORDER BY ou GROUP BY qui ne peuvent pas être améliorées avec l'optimisation de requête ou l'indexation améliorée. La mémoire tampon entière est allouée même si elle n'est pas entièrement nécessaire. Par conséquent, si vous la définissez sur une taille supérieure à celle requise globalement, la plupart des requêtes de ce type seront ralenties. Il est préférable de l'augmenter en tant que paramètre de session, et uniquement pour les sessions qui nécessitent une plus grande taille. Sous Linux, il existe des seuils de 256 Ko et 2 Mo où des valeurs plus élevées peuvent ralentir considérablement l'allocation de mémoire, vous devriez donc envisager de rester en dessous de l'une de ces valeurs. Essayez de trouver la meilleure valeur pour votre charge de travail.

À partir de 5.6, le libellé indique que l'optimiseur peut choisir une valeur pour une requête et que le serveur peut étendre le tampon jusqu'à la limite. Cela réduit le coût de définition d'une valeur trop élevée. Il semble donc que vous souhaitiez être conservateur, inférieur à la valeur par défaut (comme le font les fichiers cnf) pour les versions inférieures à 5.6.4, mais vous pouvez vous permettre d'avoir une limite supérieure de disons les 2 Mo par défaut, voire plus, à partir de 5.6. 4 car le montant total n'est pas alloué aveuglément.

Depuis MySQL 5.6.4, l'optimiseur essaie de déterminer la quantité d'espace nécessaire mais peut en allouer plus, jusqu'à la limite.

2
ClearCrescendo

Vous n'avez pas besoin de changer la valeur sort_buffer_size par défaut. Vous vous méprenez sur son utilisation en fonction de la question. Vous devez commencer par examiner le SQL pour voir si vous pouvez le régler et satisfaire les conditions ORDER BY/GROUP BY à l'aide d'un index. Ce sera généralement un indice composite.

En outre: http://www.xaprb.com/blog/2010/05/09/how-to-tune-mysqls-sort_buffer_size/

2
eroomydna

La meilleure façon de déterminer la valeur optimale sort_buffer_size est de le comparer.

Comment? Comme @RolandoMySQLDBA a dit de vérifier Sort_merge_passes peut être utile, mais ce n'est pas le seul facteur qui affecte les performances. Vous devez être prudent lorsque vous augmentez la sort_buffer_size.

Le document dit que

Sous Linux, il existe des seuils de 256 Ko et 2 Mo où des valeurs plus élevées peuvent ralentir considérablement l'allocation de mémoire, vous devriez donc envisager de rester en dessous de l'une de ces valeurs.

Il y a n post sur le test qui conclut que

sort_merge_passes ce n'est pas si mal. Configuration de votre sort_buffer_size suffisamment grand pour qu'il n'y ait aucun sort_merge_passes n'est peut-être pas optimal.

Lorsque j'ai testé, j'obtiens également un résultat similaire.

Idéalement, il serait préférable d'éviter la situation dont vous avez besoin pour optimiser le sort_buffer_size. Comment? Ce document ORDER BY Optimization pourrait vous aider à comprendre comment les choses fonctionnent sous le capot.

1
Sanghyun Lee