Je travaille actuellement sur une base de données MySQL où nous voyons un grand nombre d'invalidations du cache de requêtes, principalement en raison du nombre élevé d'instructions INSERT, DELETE et UPDATE qui sont exécutées sur de nombreuses tables.
Ce que j'essaie de déterminer, c'est s'il y a un quelconque avantage à autoriser le cache de requêtes à être utilisé pour les instructions SELECT qui sont exécutées sur ces tables. Puisqu'ils sont invalidés si rapidement, il me semble que la meilleure chose serait d'utiliser simplement SQL_NO_CACHE sur les instructions SELECT avec ces tables.
Le surcoût d'une invalidation fréquente en vaut-il la peine?
Edit: À la demande de l'utilisateur @RolandoMySQLDBA ci-dessous, voici les informations sur MyISAM et INNODB.
InnoDB
- Taille des données: 177,414 Go
- Taille de l'index: 114,792 Go
- Taille de la table: 292,205 Go
MyISAM
- Taille des données: 379,762 Go
- Taille de l'index: 80.681 Go
- Taille de la table: 460,443 Go
Information additionnelle:
- Version: 5.0.85
- query_cache_limit: 1048576
- query_cache_min_res_unit: 4096
- query_cache_size: 104857600
- query_cache_type: ON
- query_cache_wlock_invalidate: OFF
- innodb_buffer_pool_size: 8841592832
- 24 Go de RAM
Réponses:
Vous devez simplement désactiver le cache de requête avec
puis redémarrez mysql. Pourquoi est-ce que je suggérerais ça ???
Le cache de requêtes sera toujours en tête avec InnoDB. Ce serait bien si le MVCC d'InnoDB permettait aux requêtes d'être servies à partir du cache de requêtes si les modifications n'affectaient pas les lectures répétables pour d'autres transactions. Malheureusement, InnoDB ne fait tout simplement pas cela. Apparemment, vous avez beaucoup de requêtes qui sont invalidées assez rapidement et qui ne sont probablement pas réutilisées.
Pour InnoDB sous MySQL 4.0, le cache de requêtes a été désactivé pour les transactions. Pour MySQL 4.1+, InnoDB joue le flic du trafic lorsqu'il autorise l'accès au cache de requêtes par table.
Du point de vue de votre question, je dirais que la justification de la suppression du cache de requêtes n'est pas tant la surcharge, mais la façon dont InnoDB le gère.
Pour plus d'informations sur la façon dont InnoDB interagit avec le cache de requêtes, veuillez lire les pages 213 à 215 du livre "High Performance MySQL (Second Edition)" .
Si la totalité ou la majorité de vos données sont MyISAM, vous pouvez utiliser votre idée originale d'utiliser SQL_NO_CACHE.
Si vous avez un mélange d'InnoDB et de MyISAM, vous devrez trouver le bon équilibre pour votre application en fonction de la hauteur de vos échecs de cache. En fait, les pages 209-210 du même livre soulignent les raisons des échecs de cache:
et les causes profondes des échecs de cache élevés avec peu de requêtes impossibles à mettre en cache peuvent être:
MISE À JOUR 2012-09-06 10:10 EDT
À la recherche de vos dernières informations mises à jour, vous avez
query_cache_limit
défini 1048576 (1M). Cela limite tout jeu de résultats à 1M. Si vous récupérez quelque chose de plus grand, il ne sera tout simplement pas mis en cache. Bien que vous ayezquery_cache_size
défini 104857600 (100M), cela ne permet que 100 résultats mis en cache dans un monde parfait. Si vous effectuez des centaines de requêtes, la fragmentation se produira assez rapidement. Vous avez également 4096 (4K) comme jeu de résultats de taille minimale. Malheureusement, mysql n'a pas de mécanisme interne pour défragmenter le cache de requêtes.Si vous devez avoir le cache de requêtes et que vous avez tellement de RAM, vous pouvez exécuter ce qui suit:
afin de purger le cache de requête. Vous perdez tous les résultats mis en cache, exécutez donc ces lignes pendant les heures creuses.
Je voudrais également attribuer les éléments suivants:
Cela laisse 23G de RAM. Je voudrais soulever ce qui suit:
Cela laisse 7G. Cela devrait être suffisant pour les connexions OS et DB.
Gardez à l'esprit que le tampon clé ne met en cache que les pages d'index MyISAM, tandis que le pool de tampons InnoDB met en cache les données et les index.
Une autre recommandation: passez à MySQL 5.5 pour pouvoir configurer InnoDB pour plusieurs CPU et plusieurs threads pour les E / S en lecture / écriture.
Voir mes articles précédents sur l'utilisation de MySQL 5.5 en conjonction avec l'accès à plusieurs processeurs pour InnoDB
Nov 24, 2011
: Pourquoi mysql 5.5 est plus lent que 5.1 (linux, utilise mysqlslap)Oct 05, 2011
: La requête s'exécute longtemps dans certaines versions plus récentes de MySQLSep 20, 2011
: Multi-cœurs et performances MySQLJun 19, 2011
: Comment puis-je effectuer correctement une cuisson MySQL?MISE À JOUR 2012-09-06 14:56 EDT
Ma méthode pour effacer le cache de requête est plutôt extrême car elle arrose les données mises en cache et forme un segment de RAM complètement différent. Comme vous l'avez souligné dans votre commentaire,
FLUSH QUERY CACHE
(comme vous l'avez suggéré) ou même ceRESET QUERY CACHE
serait mieux. Pour plus de précision, lorsque j'ai dit "pas de mécanisme interne", je voulais dire exactement cela. La défragmentation est nécessaire et doit être effectuée manuellement. Il devrait être contrôlé .Si vous faites du DML (INSERT, UPDATEs, DELETEs) sur InnoDB plus souvent que sur MyISAM, je dirais supprimer complètement le cache de requête, ce que j'ai dit au début.
la source
FLUSH QUERY CACHE
pour le défragmenter? Voir: dev.mysql.com/doc/refman/5.0/en/flush.htmlMAUVAIS: query_cache_size = 1G
Pourquoi? En raison du temps que prendra une chasse d'eau. Autrement dit, lorsqu'une écriture se produit, l'intégralité de 1 Go sera analysé pour trouver toutes les références à la table qui a été modifiée. Plus le QC est grand, plus c'est lent. Je recommande une taille ne dépassant pas 50M, à moins que vos données ne changent rarement.
Le QC est à la fois pour MyISAM et InnoDB. Il supprime un Mutex mondial et le supprime trop tôt. Ce mutex est l'une des raisons pour lesquelles MySQL ne peut pas utiliser efficacement plus de 8 cœurs environ.
SQL_NO_CACHE n'est remarqué qu'après le verrouillage du Mutex! La seule utilisation de ce drapeau est le benchmarking.
Il est souvent préférable de donner la RAM à un autre cache.
la source
Je peux penser à un cas parfait pour cela, et nous l'avons testé et exécuté en production ... Je l'appelle la stratégie de clustering "fast lane" :
Si vous effectuez un fractionnement en lecture-écriture avec un proxy comme MaxScale, ou si votre application est capable, vous pouvez envoyer certaines des lectures de ces tables rarement invalidées uniquement aux esclaves dont le cache de requêtes est activé, et le reste à d'autres esclaves avec lui éteindre.
Nous faisons cela et traitons 4M d'appels par minute au cluster lors de nos tests de charge (pas de référence ... la vraie affaire) en conséquence. L'application attend certaines choses sur master_pos_wait (), elle est donc limitée par le thread de réplication, et bien que nous l'avons vu avec un statut d'attente sur l'invalidation de Qcache à très haut débit, ces niveaux de débit sont plus élevés que le cluster n'est même capable de sans Qcache.
Cela fonctionne car il y a rarement quelque chose de pertinent dans le cache de requête minuscule sur ces machines à invalider (ces requêtes ne sont pertinentes que pour les tables rarement mises à jour). Ces boîtes sont notre "voie rapide". Pour le reste des requêtes que l'application fait, ils n'ont pas à faire face à Qcache car ils vont dans des boîtes sans qu'il ne soit activé.
la source