2009-03-23 4 views
6

J'ai une application web php où certaines données changent sur une base hebdomadaire mais sont souvent lues très souvent.Meilleure technique de mise en antémémoire des résultats de requêtes qui changent rarement

Les requêtes SQL qui récupèrent les données et le code php pour la sortie html sont assez complexes. Il existe plusieurs jointures de tables et de nombreux calculs, mais elles aboutissent à une table html assez basique. Les utilisateurs sont regroupés et la table est la même pour chaque groupe chaque semaine, mais différente pour les différents groupes. Je pourrais potentiellement avoir des centaines de tables pour des milliers d'utilisateurs.

Pour des raisons de performances, je souhaite mettre en cache ces données. Plutôt que d'exécuter ces requêtes et calculs à chaque fois que quelqu'un accède à la page, je veux lancer un processus hebdomadaire pour générer la table pour chaque groupe en me donnant une lecture simple si nécessaire.

Je serais intéressé de savoir quelles techniques vous avez utilisées avec succès ou sans succès pour réaliser quelque chose comme ça?

Options Je peux voir les suivantes:

  • Stockage du résultat html des calculs dans une table MySQL, identifié par groupe d'utilisateurs
  • Stockage des données résultantes dans une table MySQL, identifié par groupe d'utilisateurs (difficile car il n'y a pas de nombre fixe d'éléments de données)
  • la sortie Mise en cache page dans les fichiers statiques

Toutes les autres suggestions sont les bienvenues!

Répondre

4

Il y a en effet quelques options:

  • prérendu les pages sur une base hebdomadaire et les servir ensuite « statiquement ».
  • Utilisez un cache (par exemple Squid) pour mettre en cache ces réponses sur une base de première chance pendant une semaine. Par exemple, vous pouvez configurer la stratégie de mise en cache afin que les demandes qui vont à une page particulière (par exemple very_long.php? ...) soient mises en cache séparément du reste du site Web.
  • Assurez-vous d'activer la mise en cache de la base de données. MySQL a sa propre mise en cache et vous pouvez l'affiner afin que les longues requêtes répétées ne soient pas recalculées.
+0

Quelques bonnes suggestions, merci. – Damovisa

+0

Bonne liste de suggestions ici. Notez que la mise en cache des requêtes MySQL n'est pas une solution complète - elle présente des avantages et des inconvénients (elle peut empirer les choses sur les données fréquemment mises à jour). Comme le suggère Assaf, ce n'est qu'une des nombreuses options. – thomasrutter

2

tout d'abord, le profil. vérifiez que ces requêtes consomment vraiment beaucoup de temps. peut-être que les caches de résultats de requête MySQL ont déjà fait le travail pour vous. Si elles consomment vraiment des ressources, ce que je ferais est de créer une table avec les résultats calculés, et une procédure qui doit tous être gérée, à appeler quand les données changent. ces lectures fréquentes ne devraient aller qu'aux données précalculées, sans prendre la peine de vérifier si elles sont toujours valides. Il suffit d'ajouter des raccourcis aux procédures qui modifient les données de base, ou des déclencheurs de base de données si vous le pouvez, ceux-ci seront exécutés rarement (hebdomadairement?), Et cela pourrait prendre beaucoup de temps pour générer des résultats.

+0

Je pense que c'est la première fois que je vois une question qui a quatre réponses et qui sont toutes bonnes (toutes méritant une mise à jour)! Bonnes suggestions ici. Le besoin de profiler avant d'optimiser est un bon point. – thomasrutter

+0

Vrai - J'ai été assez impressionné! – Damovisa

6

Dans la fonction pour générer la table, faire stocker le résultat dans un fichier sur le disque:

/cache/groups/1.txt 
/cache/groups/2.txt 

Vous ne devez pas nécessairement courir pour elle, un traitement par lots hebdomadaire lorsque vous appelez la fonction obtenir les données, vérifier si le cache est obsolète (ou inexistant).Si c'est le cas, générez et cachez les résultats ensuite. Sinon, renvoyez simplement le fichier en cache.

function getGroupTable($groupId) { 
    if (cacheIsStale($groupId)) { 
     generateCache($groupId); 
    } 
    return file_get_contents($cacheFile); 
} 

La fonction cacheIsStale() pourrait simplement regarder le file's timestamps pour tester la fraîcheur.

+0

Voilà comment j'ai géré un tel problème il y a longtemps. –

+0

C'est une bonne solution et probablement celle que j'utiliserai. Je suis juste préoccupé par le besoin potentiel (futur) d'utiliser les données générées plutôt que seulement le HTML. – Damovisa

+0

dans ce cas, vous pourriez peut-être stocker les résultats de MySQL dans un format différent, plus accessible. CSV fonctionne facilement (la fonction fgetcsv aide ici), ou vous pouvez même placer le résultat dans un tableau, puis le sérialiser. Bien sûr, vous pouvez faire deux fichiers cache: HTML ainsi que des données brutes. – nickf

2

Il semble que vous en ayez déjà couvert la plus grande partie. Une autre option, en supposant que les données de la table ne sont pas énormes, est d'utiliser memcache pour mettre en cache les résultats - ce serait probablement la solution la plus rapide, bien que vous ayez besoin de vérifier la mémoire pour voir si c'est une option viable.

Questions connexes