Das erste und gravierendste Leistungsproblem, das bei NHibernate auftreten kann, ist die Erstellung einer neuen Session Factory für jede erstellte Session. Für jede Anwendungsausführung sollte nur eine Instanz der Sitzungsfabrik erstellt werden, und alle Sitzungen sollten von dieser Fabrik erstellt werden.
In diesem Sinne sollten Sie die gleiche Sitzung so lange verwenden, wie es sinnvoll ist. Dies ist je nach Anwendung unterschiedlich, aber für die meisten Webanwendungen wird eine einzige Sitzung pro Anfrage empfohlen. Wenn Sie Ihre Sitzung häufig wegwerfen, profitieren Sie nicht von den Vorteilen des Sitzungscaches. Ein intelligenter Einsatz des Sitzungscaches kann eine Routine mit einer linearen (oder schlechteren) Anzahl von Abfragen ohne viel Aufwand in eine konstante Anzahl verwandeln.
Ebenso wichtig ist es, dass Sie sicherstellen, dass Sie Ihre Objektreferenzen mit Verzögerung laden. Andernfalls könnten selbst bei den einfachsten Abfragen ganze Objektgraphen geladen werden. Es gibt nur bestimmte Gründe, dies nicht zu tun, aber es ist immer besser, mit "lazy loading" zu beginnen und bei Bedarf zurückzuschalten.
Das bringt uns zu eager fetching, dem Gegenteil von lazy loading. Beim Durchqueren von Objekthierarchien oder beim Durchlaufen von Sammlungen kann man leicht den Überblick über die Anzahl der Abfragen verlieren, so dass man am Ende eine exponentielle Anzahl von Abfragen hat. Eifriges Abrufen kann für jede Abfrage mit einem FETCH JOIN durchgeführt werden. In seltenen Fällen, z. B. wenn es ein bestimmtes Tabellenpaar gibt, das Sie immer abrufen, können Sie das "Lazy Loading" für diese Beziehung deaktivieren.
Wie immer ist der SQL Profiler eine gute Möglichkeit, Abfragen zu finden, die langsam laufen oder wiederholt durchgeführt werden. Bei meiner letzten Tätigkeit hatten wir eine Entwicklungsfunktion, die auch die Abfragen pro Seitenanforderung zählte. Eine hohe Anzahl von Abfragen für eine Routine ist der offensichtlichste Indikator dafür, dass Ihre Routine nicht gut mit NHibernate zusammenarbeitet. Wenn die Anzahl der Abfragen pro Routine oder Anfrage gut aussieht, liegt es wahrscheinlich an der Abstimmung der Datenbank; stellen Sie sicher, dass Sie genügend Speicher haben, um Ausführungspläne und Daten im Cache zu speichern, indizieren Sie Ihre Daten korrekt usw.
Ein kniffliges kleines Problem trat bei SetParameterList() auf. Die Funktion ermöglicht die einfache Übergabe einer Liste von Parametern an eine Abfrage. NHibernate implementiert dies, indem es für jedes übergebene Element einen Parameter erstellt. Dies führt zu einem anderen Abfrageplan für jede Anzahl von Parametern. Unsere Ausführungspläne wurden fast immer aus dem Cache freigegeben. Außerdem können zahlreiche Parameter eine Abfrage erheblich verlangsamen. Wir haben NHibernate so angepasst, dass die Elemente als durch Trennzeichen getrennte Liste in einem einzigen Parameter gesendet werden. Die Liste wurde in SQL Server durch eine Tabellenwertfunktion getrennt, die unser Hack automatisch in die IN-Klausel der Abfrage einfügte. Abhängig von Ihrer Anwendung kann es noch weitere solche Minen geben. SQL Profiler ist der beste Weg, um sie zu finden.