Frage

Ich habe eine Anwendung, die NHibernate als ORM verwendet und manchmal erfährt es Performance-Probleme durch, wie die Daten, die durch sie zugegriffen wird. Welche Art von Dingen kann getan werden, um die Leistung von NHibernate zu verbessern? (Bitte beschränken auf eine Empfehlung pro Antwort)

War es hilfreich?

Lösung

Die erste und dramatische Performance-Problem, das Sie in mit NHibernate ausgeführt werden können, wenn Sie eine neue Sitzung Fabrik für jede Sitzung erstellen Sie erstellen. Es sollte nur eine Sitzung Factory-Instanz für jede Anwendung der Ausführung und alle Sitzungen erstellt werden sollen von dieser Fabrik erstellt werden.

In diese Richtung sollten Sie so lange mit der gleichen Sitzung fortsetzen, wie es Sinn macht. Dies variiert von Anwendung, aber für die meisten Web-Anwendungen, eine einzige Sitzung pro Anfrage wird empfohlen. Wenn Sie Ihre Sitzung häufig wegzuwerfen, gewinnen Sie nicht die Vorteile seiner Cache. Intelligently unter Verwendung des Sitzungs Cache eine Routine mit einem linearen (oder schlechter) Anzahl der Abfragen auf eine konstante Zahl ohne viel Arbeit ändern.

Ebenso wichtig ist, dass Sie sicherstellen möchten, dass Sie faul sind, laden Sie Ihre Objektreferenzen. Wenn Sie nicht, könnten ganze Objekt sind grafische Darstellungen, selbst für die einfachen Abfragen geladen werden. Es gibt nur bestimmte Gründe, dies nicht zu tun, aber es ist immer besser, mit verzögertes Laden zu starten und bei Bedarf wechseln.

Das bringt uns zu eifrig fetching, das Gegenteil von dem verzögertes Laden. Während Objekthierarchien durchquert oder durch Sammlungen Looping, kann es leicht sein, den Überblick zu verlieren, wie viele Abfragen, die Sie machen und Sie mit einer exponentiellen Anzahl von Anfragen am Ende. Eager fetching kann mit einem FETCH JOIN auf einer pro Abfrage Basis durchgeführt werden. In seltenen Fällen, wie zum Beispiel, wenn es ein bestimmtes Paar von Tabellen, die Sie immer verbinden holen, betrachten verzögertes Laden für diese Beziehung ausgeschaltet werden.

Wie immer ist SQL Profiler eine gute Möglichkeit, Anfragen zu finden, die langsam ausgeführt werden oder wiederholt durchgeführt werden. Bei meinem letzten Job hatten wir eine Entwicklung Funktion, die auch Abfragen pro Seite Anfrage gezählt. Eine hohe Anzahl von Anfragen für eine Routine ist der offensichtlichste Indikator dafür, dass Ihre Routine mit NHibernate nicht gut funktioniert. Wenn die Anzahl der Anfragen pro Routine oder fordern Sie sieht gut aus, Sie sind wahrscheinlich bis zu Datenbank-Tuning; dafür, dass Sie genügend Speicherplatz zum Speichern von Ausführungsplänen und Daten im Cache, richtig Indizierung Ihrer Daten, etc.

haben

Ein kniffliges kleines Problem, das ich lief in war mit SetParameterList (). Die Funktion ermöglicht es Ihnen, auf einfache Weise eine Liste von Parametern auf eine Abfrage übergeben. NHibernate realisiert dies, indem für jedes Element einen Parameter Erstellung übergeben. Dies führt zu einem anderen Abfrage-Plan für jede Anzahl von Parametern. Unsere Ausführungspläne wurden fast immer aus dem Cache freigegeben zu werden. Außerdem können zahlreiche Parameter signifikant eine Abfrage verlangsamen. Wir haben eine benutzerdefinierte Hack von NHibernate die Elemente als getrennte Liste in einem einzigen Parameter zu senden. Die Liste wurde in SQL Server durch eine Tabellenwertfunktion, die unser Hack automatisch in die IN-Klausel der Abfrage eingefügt getrennt. Es könnten auch andere Landminen so sein, je nach Anwendung. SQL Profiler ist der beste Weg, um sie zu finden.

Andere Tipps

NHibernate Session ist eine teuere Operation so eine gute Strategie, um eine Singleton schafft, ist die, dass es gewährleistet nur eine Instanz der Session im Speicher:

   public class NHibernateSessionManager
    {
        private readonly ISessionFactory _sessionFactory;

        public static readonly NHibernateSessionManager Instance = new NHibernateSessionManager();

        private NHibernateSessionManager()
        {
            if (_sessionFactory == null)
            {
                System.Diagnostics.Debug.WriteLine("Factory was null - creating one");
                _sessionFactory = (new Configuration().Configure().BuildSessionFactory());
            }
        }

        public ISession GetSession()
        {
            return _sessionFactory.OpenSession();
        }

        public void Initialize()
        {
            ISession disposeMe = Instance.GetSession();
        }
    }

Dann in Ihrem Global.asax Application_Startup, können Sie es initialisieren:

protected void Application_Start()
{
    NHibernateSessionManager.Instance.Initialize();
}

Vermeiden und / oder zu minimieren, das wählen N + 1 Problem durch erkennen, wenn von träges Laden wechseln eifrig für langsames Durchführen einer Abfrage abgerufen werden.

Keine Empfehlung, sondern ein Werkzeug, um Ihnen zu helfen: NH Prof ( http://nhprof.com/ ) scheint sein vielversprechend, kann es um Ihre Nutzung des ORM-Framework bewerten. Es kann ein guter Ausgangspunkt für Ihren tunning von NHibernate sein.

Ohne Einzelheiten über die Art der Performance-Probleme Sie sehen, kann ich bieten nur eine Verallgemeinerung: Meiner Erfahrung nach entstehen die meisten Datenbankabfrageleistung Fragen aus Mangel an geeigneten Indizes. Also mein Vorschlag für eine erste Aktion wäre Ihre Abfragepläne für nicht-indizierte Abfragen zu überprüfen.

NHibernate erzeugt ziemlich schnell SQL direkt aus der Box. Ich habe ein Jahr lang mit ihm, und habe noch nackte SQL mit ihm habe zu schreiben. Alle meine Performance-Probleme aus haben Normalisierungs und das Fehlen von Indizes.

Die einfachste Lösung ist es, die Ausführungspläne Ihrer Abfragen zu untersuchen und geeignete Indizes erstellen, vor allem auf dem Fremdschlüsselspalten. Wenn Sie Microsoft SQL Server verwenden, hilft die "Database Engine Tuning Advisor" dies viel mit aus.

„Eine Empfehlung pro Antwort“ nur? Dann würde ich für diesen einen gehen:

Vermeiden Sie Duplikate join (AKA kartesische Produkte) aufgrund schließt sie entlang von zwei oder mehr parallel zu vielen Vereinen; Verwenden Sie exists-Unterabfragen, Multiqueries oder FetchMode "subselect" statt.

Entnommen: Hibernate Performance Tuning Tipps

Ich bin nur zu begrenzen, meine Antwort auf eine Option erlaubt? In diesem Fall würde ich wählen, dass Sie den Second-Level-Cache-Mechanismus von NHibernate implementieren.

Auf diese Weise für jedes Objekt in der Mapping-Datei können Sie die Cache-Strategie definieren. Der Cache wird Secondlevel halten bereits Objekte im Speicher abgerufen und daher nicht eine andere Rundreise an der Datenbank vornehmen. Dies ist eine enorme Leistungsverstärker.

Ihr Ziel ist es, die Objekte zu definieren, die von der Anwendung ständig zugegriffen werden. Unter denen, werden die allgemeinen Einstellungen und dergleichen.

Es gibt viele Informationen für nhibernate Second Level Cache und zu dessen Implementierung gefunden werden.

Viel Glück:)

Caching, Caching, Caching - Sind Sie mit Ihrem ersten Level-Caching richtig [Schließen Sitzungen vorzeitig oder mit StatelessSession ersten Level-Caching umgehen]? Sie benötigen einen einfachen Cache zweiter Ebene für Werte einrichten, die sich selten ändern? Können Sie Abfrageergebnisse Cache-Abfragen zu beschleunigen, die selten ändern?

[auch Konfiguration - können Sie Elemente als unveränderlich festgelegt? Können Sie Anfragen restrukturieren nur die Informationen, die Sie benötigen, um wieder und sie in die ursprüngliche Einheit zu verwandeln? Wird Batman Lage sein, den Riddler zu stoppen, bevor er zur Mutter bekommt? ... oh, und es erfolgt leider weg.]

Profilieren ist der erste Schritt - selbst einfache timed Unit-Tests -, um herauszufinden, wo die größten Gewinne gemacht werden können

Für Sammlungen betrachten die Einstellung der Chargengröße, die Anzahl der select-Anweisungen ausgegeben zu reduzieren - siehe Abschnitt Verbesserung der Leistung Details

Wenn Sie nicht bereits ein träges Laden mit (entsprechend), starten. Holen von Sammlungen, wenn Sie brauchen sie nicht eine Verschwendung von allem.

Kapitel Leistung Verbesserung beschreibt diese und andere Möglichkeiten, um die Leistung zu verbessern.

Was lotsoffreetime sagte.

Lesen Sie Kapitel 19 der Dokumentation „Die Verbesserung der Performance“.
NHibernate: http://nhibernate.info/doc/nhibernate-reference/performance.html
Hibernate: http://docs.jboss.org/ hibernate / core / 3.3 / Referenz / en / html / performance.html

Verwenden Sie SQL Profiler (oder gleichwertig für die Datenbank verwenden Sie) lang laufende Abfragen zu lokalisieren. diese Abfragen mit entsprechenden Indizes optimieren.

Für Datenbankaufrufe auf fast jede einzelne Seite einer Anwendung verwendet wird, verwenden CreateMultiQuery mehrere Resultsets aus einer einzigen Datenbank-Abfrage zurückzukehren.

Und natürlich Cache. Der Output Direktive für Seiten / Kontrollen. NHibernate-Caching für Daten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top