2011-05-20 3 views
4

Je développe une application MVC avec NHibernate en utilisant le modèle de session par requête. La plupart du temps, les utilisateurs lisent simplement les données et j'essaie donc d'utiliser le cache de second niveau de NHibernate de la manière suivante: J'ai configuré SysCache et j'ai rendu toutes mes entités persistantes cachables (utilisation du cache = "nonstrict-read-write") et le démarrage de l'application, je fais des appels à charger toutes les entités couramment utilisées à partir de la base de données comme ceci:Problème de performances du cache de second niveau NHibernate

var all = Session.QueryOver<T>().Cacheable().List<T>() 

aux fins d'évaluation, je trace le temps d'exécution de l'appel ci-dessus et pour environ 50 000 résultats, il est environ 5 secondes le premier temps et ~ 2,5 secondes pour tous les appels ultérieurs à la requête en cache .... NHibernate Profiler dit que la requête à la base de données prend moins de 100ms, ce qui prend tellement de temps alors? J'ai essayé de changer de fournisseur mais j'ai obtenu des résultats similaires (sinon pire) avec Velocity et Memcached ... J'ai lu pratiquement tout ce que j'ai pu trouver sur NHibernate et son utilisation du cache de second niveau et je pense que dans la déclaration ci-dessus, ce qui se passe est: 50000 objets sont construits et leurs données sont stockées dans l'entité et les caches de requête et l'horodatage de session enregistré dans le cache d'horodatage. Comment cela peut-il prendre 5 secondes sur une machine i5? Même si c'est normal comment juste lire les données mises en cache prendre 2.5 secondes dans les appels suivants sans aucun changement entre les deux? Comme je suis relativement nouveau à NHibernate, est-ce que l'un d'entre vous peut m'aider à comprendre ce que je fais de mal? Toute aide serait grandement appréciée ... Je me suis cogné la tête contre le mur pendant une semaine maintenant ...

Répondre

4

Vous ne devriez pas mettre 50000 entités dans votre cache, cela nie le point d'avoir une base de données, surtout si vos données proviennent d'un SELECT * FROM TABLE. Si elle provient d'une requête VRAIMENT coûteuse, le coût de la mise en cache est inférieur au coût de la requête et doit être placé dans le cache.

Utilisez des requêtes pour obtenir des données spécifiques. Ensuite, recherchez les pages qui génèrent le plus de requêtes et optimisez-les en utilisant un cache si nécessaire.

+0

Nous vous remercions de votre réponse rapide. Bien que je sois récemment arrivé à réaliser que ce que vous dites est effectivement la façon d'utiliser NH (et les requêtes non spécifiques comme la mienne ci-dessus même déclencher une alerte dans le profileur NH), seules les requêtes coûteuses devraient être mises en cache, à condition que les données soient rarement modifiées ? En outre, je travaille à la conception de la couche d'accès aux données de telle sorte que seules des requêtes ou requêtes spécifiques avec un ensemble de résultats liés seront publiées, mais je suis néanmoins intéressé par ce qui peut être la cause du coût énorme de la déclaration , afin de découvrir tous les problèmes de mise en cache que je pourrais avoir ... –

+1

Utilisez la mise en cache pour les requêtes fréquemment appelées et définissez la date d'expiration en fonction de la fréquence de modification. – mathieu

+1

juste pour développer la réponse très correcte de @ mathieu- Je crois que votre hypothèse est correcte: le temps d'exécution long provient du fait que le cache nHib enregistre réellement les propriétés des objets mis en cache et leurs valeurs, et non des objets entiers. les objets eux-mêmes sont construits à chaque lecture. donc ce sont vos 2,5 secondes. –

Questions connexes