2010-01-14 9 views
0

Je dois implémenter le cache pour les requêtes SQL. Disons que nous avons SELECT id,aa,bb FROM table1 WHERE aa>1 and bb=12; - nous voulons qu'il soit mis en cache. En outre, il peut être SELECT id,aa,bb FROM table1 WHERE aa>25 and bb=11; ou SELECT id,aa,bb FROM table2; bien sûr. Ce n'est pas grave - la question est de savoir comment expirer mieux les valeurs de cache. Sur les mises à jour Disons, nous avons ajouté une nouvelle ligne avec INSERT ... ou mis à jour les données existantes avec UPDATE .... Nous devons expirer tout le cache qui avait des valeurs de SELECT, car ils ne sont peut-être plus précis.Mise en œuvre pour la mise en cache des requêtes

Comment faire cela mieux?

Dans le cas le plus simple - nous utilisons toute la clé de requête "Requête SQL" dans le cache. Mais au moment de INSERT/UPDATE nous n'avons aucune idée quelles requêtes expirer (quelles clés?)

Répondre

0

Une chose que j'ai faite avant est de faire une liste de clés de cache et de stocker cela dans le cache.

Lorsque j'ai besoin de mettre en cache quelque chose, je récupère la liste, y ajoute la clé et la stocke dans le cache. Ensuite, lorsque j'ai besoin d'effacer le cache pour un ensemble particulier, j'attrape la liste et supprime toutes les clés de la liste du cache et supprime la liste du cache. J'ai l'impression que certaines bibliothèques de cache par exemple dans NHibernate fonctionnent aussi, mais je ne suis pas tout à fait sûr de cela.

+0

C'était mon idée initiale - il y a certains inconvénients. - Comme lorsque deux serveurs tentent de modifier en même temps la «liste des clés de cache» (le détenteur), une clé de cache peut être facilement perdue. Cependant, il semble être un petit prix à payer. – alexeypro

+0

C'est un très bon point. Je n'ai pas encore rencontré de problèmes, mais ce serait possible. Jusqu'à présent, dans les cas où j'ai dû le faire manuellement, les données ne changent pas si souvent. –

0

C'est pourquoi la recommandation générale est pas tentative d'utiliser memcached comme un cache de requête.

Vous avez une sorte de modèle représenté à l'extrémité inférieure par une base de données et l'extrémité supérieure par une API. Vous devriez mettre en cache près de cette API.

Par exemple, ne pas penser à SELECT id,aa,bb FROM table1 WHERE aa>1 and bb=12; comme une opération, mais penser aux opérations plus comme suit:

bbObject = BBObject.get(12); # reusable and independently cached BB instance. 
bbObject.getAAs()   # Another reusable and independently cacheable obj 

Avec cela, vous avez la structure de travailler avec et il devrait être plus évident comment utilisez ceci.

Par exemple, quel que soit table1 représente ici (se référant à aa car c'est ce que je suis en mesure d'inférer de votre exemple).

# save a new aa in `table1` and invalidate the `bbObject.getAAs` cache(s) 
aa AA.new(bbObject, 5).save() 
+0

Ce n'est pas clair. Comment puis-je invalider l'objet de requête dans le cache qui remplit aa> 1 (il peut avoir aa = 1000 et 99.9 et ce n'est pas le cas)? – alexeypro