Quel est le meilleur moyen pour améliorer les performances de NHibernate?
J'ai une application qui utilise NHibernate comme son ORM et parfois, elle fait l'expérience de problèmes de performance en raison de la façon dont les données sont accessibles par elle. Quel genre de choses qui peut être fait pour améliorer les performances de NHibernate? (Merci de vous limiter à une recommandation par réponse)
Vous devez vous connecter pour publier un commentaire.
La première et la plus dramatique problème de performance que vous pouvez exécuter dans NHibernate est si vous êtes à la création d'une nouvelle session de l'usine pour chaque session que vous créez. Une seule session d'usine instance doit être créé pour chaque exécution de l'application, et toutes les sessions devraient être créés par cette usine.
Le long de ces lignes, vous devez continuer à utiliser la même session en tant qu'il a du sens. Cela peut varier selon l'application, mais pour la plupart des applications web, une seule session par demande est recommandé. Si vous jetez votre session fréquemment, vous n'êtes pas gagner les avantages de son cache. En utilisant intelligemment le cache de session peut changer une routine avec un linéaire (ou pire) nombre de requêtes à un nombre constant sans beaucoup de travail.
Tout aussi important, c'est que vous voulez vous assurer que vous êtes paresseux chargement de vos références d'objet. Si vous n'êtes pas, ensemble d'objets graphiques peuvent être chargées, même pour le plus simple des requêtes. Il y a seulement un certain nombre de raisons de ne pas le faire, mais il est toujours préférable de commencer avec un chargement différé et de revenir en tant que de besoin.
Qui nous amène à chargement agressif, à l'opposé de chargement paresseux. En parcourant les hiérarchies de supports ou en boucle à travers les collections, il peut être facile de perdre la trace de combien de requêtes vous faites et vous vous retrouvez avec un nombre exponentiel de requêtes. Le chargement agressif peut être fait par requête avec une EXTRACTION REJOINDRE. Dans de rares circonstances, comme si il ya une paire particulière de tables que vous avez toujours chercher rejoindre, pensez à désactiver le chargement paresseux pour cette relation.
Comme toujours, le générateur de profils SQL est un excellent moyen de trouver les requêtes qui sont en cours d'exécution lente ou être fait à plusieurs reprises. Lors de mon dernier emploi, nous avons eu un développement qui a compté de requêtes par page demande. Un nombre élevé de requêtes pour une routine est l'indicateur le plus évident que votre routine ne fonctionne pas bien avec NHibernate. Si le nombre de requêtes par routine ou de la demande semble bon, vous êtes probablement en bas de paramétrage des bases de données; s'assurer que vous avez suffisamment de mémoire pour stocker les plans d'exécution et les données dans le cache, correctement indexation de vos données, etc.
Un délicat problème que nous avons rencontré était avec SetParameterList(). La fonction vous permet de passer facilement à une liste de paramètres à une requête. NHibernate mis en œuvre en créant un paramètre pour chaque élément passé en. Il en résulte un plan de requête différent pour chaque nombre de paramètres. Nos plans d'exécution ont été presque toujours d'être libéré de la mémoire cache. Aussi, de nombreux paramètres peuvent considérablement ralentir une requête. Nous avons fait une coutume hack de NHibernate d'envoyer les articles que d'une liste délimitée par des virgules dans un unique paramètre. La liste a été séparé dans SQL Server par une table de la fonction de valeur que notre hack automatiquement inséré dans la DANS la clause de la requête. Il pourrait y avoir d'autres mines terrestres comme ceci en fonction de votre application. Le générateur de profils SQL est le meilleur moyen de les trouver.
NHibernate la SessionFactory est une opération coûteuse, donc une bonne stratégie est de crée un Singleton qui garantit qu'il n'existe qu'UNE seule instance de SessionFactory dans la mémoire:
Ensuite dans votre Global.Asax Application_Startup, vous pouvez l'initialiser:
Éviter et/ou réduire la Sélectionnez N + 1 problème en reconnaissant quand passer du lazy loading pour le chargement agressif pour la lenteur de l'exécution des requêtes.
Pas une recommandation mais un outil pour vous aider à : NH Prof ( http://nhprof.com/ ) semble prometteur, il peut évaluer votre utilisation de l'ORM. Il peut être un bon point de départ pour votre préparation de NHibernate.
Sans détails sur les types de problèmes de performance que vous avez vu, je ne peux que proposer une généralisation: Dans mon expérience, la plupart requête de base de données de performances de questions se posent à partir de ce manque d'indices. Donc, ma suggestion pour une première action serait de vérifier vos plans de requête pour non-indexé requêtes.
NHibernate génère assez vite SQL droit sorti de la boîte.
Je l'ai utilisé pendant un an, et n'ont pas encore eu à écrire nu SQL avec elle.
Tous mes problèmes de performance ont été à partir de La normalisation et le manque d'indices.
La meilleure solution est d'examiner les plans d'exécution des requêtes et créer des index appropriés, en particulier sur votre colonnes de clé étrangère. Si vous utilisez Microsoft SQL Server, le "Paramétrage du Moteur de Base" aide beaucoup avec cela.
"Une recommandation pour répondre à" seulement? Ensuite, je voudrais aller pour cette fois:
Éviter de rejoindre les doublons (AKA les produits cartésiens) en raison de la rejoint le long de deux ou plus en parallèle à de nombreuses associations; utiliser Existe-sous-requêtes, MultiQueries ou FetchMode "sélectionner" à la place.
Prises à partir de: Hibernate De Réglage Des Performances De Conseils
Je suis seulement permis de limiter ma réponse à une option? Dans ce cas, je voudrais que vous sélectionnez mettre en œuvre le cache de second niveau mécanisme de NHibernate.
De cette façon, pour chaque objet dans votre fichier de mappage, vous êtes en mesure de définir le cache-stratégie. Le secondlevel cache gardera déjà récupéré les objets en mémoire et, par conséquent, pas faire un aller-retour à la base de données. C'est une énorme performance de rappel.
Votre objectif est de définir les objets qui sont constamment accessibles par votre application. Parmi ceux-ci vont être les paramètres généraux et la comme.
Il y a beaucoup d'informations sont disponibles pour nhibernate du cache de second niveau et comment la mettre en œuvre.
Bonne chance 🙂
La mise en cache, Cache, Cache -- Êtes-vous à l'aide de votre premier niveau de mise en cache correctement [clôture des sessions prématurément, ou à l'aide de statelesssession n'contourner premier niveau de mise en cache]? Avez-vous besoin de mettre en place un simple cache de second niveau pour les valeurs qui changent rarement? Pouvez vous cache ensembles de résultats de requête afin d'accélérer les requêtes qui changent rarement?
[Configuration -- pouvez-vous définir des éléments comme immuable? Pouvez-vous restructurer les requêtes de ramener uniquement les informations dont vous avez besoin et de les transformer dans l'entité d'origine? Sera Batman être en mesure d'arrêter l'homme-mystère avant qu'il arrive à la construction du barrage? ... oh, désolé suis emporté.]
Profilage est la première étape, même simple chronométré tests unitaires trouver d'où les gains les plus importants peuvent être faits
Pour les collections envisager de fixer la taille du lot de réduire le nombre d'instructions select émises - voir la section L'amélioration de la performance pour plus de détails
Si vous n'êtes pas déjà en utilisant un chargement différé (de manière appropriée), démarrer. L'extraction de collections, quand vous n'avez pas besoin d'eux est une perte de tout.
Chapitre de l'Amélioration de la performance décrit ce et d'autres moyens pour améliorer la performance.
Ce lotsoffreetime dit.
Lire le Chapitre 19 de la documentation, "Amélioration des Performances".
NHibernate: http://nhibernate.info/doc/nhibernate-reference/performance.html
Hibernate: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html
Utilisation du générateur de profils SQL (ou l'équivalent pour la base de données que vous utilisez) pour localiser les requêtes de longue durée. Optimiser les requêtes avec les index appropriés.
Pour les appels de base de données utilisé sur presque chaque page de l'application, de l'utilisation CreateMultiQuery de retour de plusieurs jeux de résultats à partir d'une seule requête de base de données.
Et bien sûr, la mise en cache. La directive OutputCache pour les pages/controls. NHibernate la mise en cache pour les données.