Est-ce que MySQL cache les requêtes?

19

J'interface une base de données MySQL avec PHP Data Objects (PDO) et exécute une requête SQL étendue. Normalement, cela prend environ 1500 ms; J'ai encore besoin de l'optimiser. Lorsque j'exécute le script PHP deux fois avec un court intervalle entre les deux, la requête ne prend que 90 ms environ. La requête est dans les deux cas la même. Lorsque j'exécute le script, avec la même requête, après un certain temps, cela prend à nouveau 1500 ms.

Pourquoi donc? La base de données se cache-t-elle automatiquement? Y a-t-il un certain temps que la base de données enregistre le cache puis le supprime automatiquement?

Je suppose que les résultats ne peuvent pas être mis en cache par PHP, car cela se produit dans deux threads différents. Je ne pense pas que PHP mettrait en cache les résultats, car il ne peut pas savoir si la base de données a changé.

J'ai un script qui s'exécute toutes les minutes pour insérer de nouvelles lignes dans la base de données. Cela peut également être la raison pour laquelle il faut à nouveau 1500 ms après un certain temps; le cache aurait été supprimé, car les tables pertinentes ne sont plus les mêmes.

Peter Mortensen
la source
Montrez-moi votre code. Je n'ai pas besoin de votre requête, juste un moyen de la tester.
3
Oui, mySQL met en cache les requêtes. C'est intelligent comme ça.
@Kasyx quel code? C'est juste un PDO basique, mais je ne pense pas que PHP puisse le mettre en cache car j'exécute le script PHP deux fois, je n'exécute pas la requête deux fois dans un script. Pouvez-vous également expliquer pourquoi vous avez modifié pdo in alors qu'il n'est pas vraiment pertinent pour la question?
3
Tous les SGBD ont une sorte de cache au niveau de la page. Beaucoup vont au-delà de cela en mettant en cache les plans d'exécution des requêtes ou même les résultats des requêtes (y compris MySQL ). Je soupçonne que cette dernière chose est le principal coupable de votre comportement observé.
Branko Dimitrijevic
Tu fais des encarts toutes les minutes? Triez cela d'abord!
Grant Thomas

Réponses:

15

Il s'agit probablement d'un artefact du cache de requêtes MySQL .

Vous exécutez la requête SQL, MySQL met en cache son résultat et la prochaine exécution si rapide. Lorsque vous exécutez le script pour insérer les données dans les tables référencées par votre requête, le cache de résultats est invalidé et la requête doit être exécutée "pour de vrai" la prochaine fois.

De la documentation MySQL liée ci-dessus:

Un mélange de requêtes composé presque entièrement d'un ensemble fixe d'instructions SELECT est beaucoup plus susceptible de bénéficier de l'activation du cache qu'un mélange dans lequel des instructions INSERT fréquentes provoquent une invalidation continue des résultats dans le cache.

Branko Dimitrijevic
la source
5

Oui, mySQL (en commun avec tous les autres produits de base de données populaires) met en cache les requêtes qui lui sont adressées.

La mise en cache est assez intelligente - elle peut souvent utiliser un cache pour une requête même si les paramètres exacts de la requête ne sont pas les mêmes. Cela peut faire une grande différence dans les performances.

La mise en cache est entièrement contrôlée à l'intérieur du logiciel serveur DB; vous n'avez aucune visibilité de ce que contient le cache, ni de la durée pendant laquelle un élément donné reste dans le cache; il peut être écrasé à tout moment en fonction de ce que les autres requêtes sont appelées, etc. Il est là pour améliorer les performances, mais il ne doit pas être utilisé pour les performances.

Vous pouvez en savoir plus à ce sujet ici dans le manuel MySQL .

En outre, l'utilisation de PDO vous permet d'écrire vos requêtes en tant que «instructions préparées», en liant les paramètres plutôt qu'en les codant en dur dans une chaîne de requête en texte brut. Cela a également une implication de mise en cache sur le serveur de base de données et pour les requêtes répétées, améliorera également les performances.


la source
2
"Depuis MySQL 5.1.17, le cache de requêtes est utilisé pour les instructions préparées dans les conditions décrites dans Section 8.6.3.1," Fonctionnement du cache de requêtes ". Avant le 5.1.17, le cache de requêtes n'est pas utilisé pour les instructions préparées." dev.mysql.com/doc/refman/5.1/en/query-cache.html
1
" en commun avec tous les autres produits de base de données populaires ": c'est un peu trompeur. Pratiquement aucun SGBD ne met activement en cache les résultats des requêtes comme le fait MySQL. SGBD généralement table de cache (ou index) des données , pas Regrouper les résultats . La plupart d'entre eux mettent en cache le plan d'exécution de requête (et la requête "source")
a_horse_with_no_name
3
"il peut souvent utiliser un cache pour une requête même si les paramètres exacts de la requête ne sont pas les mêmes" est complètement incorrect. La requête doit être octet par octet identique à une requête précédemment exécutée et toujours mise en cache pour être servie à partir du cache. Même la différence entre SELECT *et select *signifie qu'une requête par ailleurs identique ne sera pas servie à partir du cache. dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html . Lien 5.1 publié pour la cohérence, mais s'applique à toutes les versions.
Michael - sqlbot