Wann sollte man die Lazy-Loading Funktion von NHibernate vermeiden?

8

Das meiste, was ich über das Lazy-Laden von NHibernate höre, ist, dass es besser ist, es zu benutzen, als es nicht zu benutzen. Es scheint, dass es nur Sinn macht, den Datenbankzugriff zu minimieren, um Engpässe zu reduzieren. Aber wenige Dinge kommen ohne Kompromisse, sicherlich begrenzt es Design leicht, indem Sie gezwungen werden, virtual Eigenschaften zu haben. Aber ich habe auch bemerkt, dass einige Entwickler das Lazy-Loading für bestimmte häufig verwendete Objekte ausschalten.

Ich frage mich, ob es bestimmte Situationen gibt, in denen die Datenzugriffsleistung durch Lazy-Loading beeinträchtigt wird.

Ich frage mich also, wann und in welchen Situationen ich es vermeiden sollte, eines meiner NHibernate-persistenten Objekte zu laden?

Besteht die Kehrseite des Lazy-Loads lediglich in der zusätzlichen Verarbeitungszeit oder kann das Lazy-Loading auch die Datenzugriffszeit erhöhen (zB durch zusätzliche Round-Trips in die Datenbank)?

Danke!

    
Mark Rogers 05.11.2009, 17:20
quelle

5 Antworten

19

Es gibt deutliche Leistungseinbußen zwischen "eager" - und "tracial loading" -Objekten aus einer Datenbank.

Wenn Sie eifrig laden, saugen Sie eine Tonne Daten in einer einzigen Abfrage, die Sie dann zwischenspeichern können. Dies ist am häufigsten beim Start der Anwendung. Sie handeln Speicherverbrauch für Datenbank-Rundreisen.

Wenn Sie Lazy Loading verwenden, saugen Sie eine minimale Menge an Daten in einer einzelnen Abfrage ab, aber jedes Mal, wenn Sie mehr Informationen zu diesen Anfangsdaten benötigen, sind mehr Abfragen an die Datenbank erforderlich Engpass in den meisten Anwendungen.

Im Allgemeinen möchten Sie also immer genau die Daten abrufen, die Sie für die gesamte Arbeitseinheit benötigen ", nicht mehr und nicht weniger. In einigen Fällen wissen Sie möglicherweise nicht genau, was Sie benötigen (weil der Benutzer mit einem Assistenten oder ähnlichem arbeitet), und in diesem Fall ist es wahrscheinlich sinnvoll, während des Betriebs zu warten.

Wenn Sie ein ORM verwenden und sich darauf konzentrieren, Features schnell hinzuzufügen und später wieder zu arbeiten und die Leistung zu optimieren (was sehr häufig ist und ein guter Weg, Dinge zu tun), ist es die richtige Art, zu gehen. Wenn Sie später (durch Leistungsprofilerstellung / Analyse) feststellen, dass Sie eine Abfrage zum Abrufen eines Objekts und anschließend N Abfragen zum Abrufen der mit diesem ursprünglichen Objekt verknüpften N-Objekte haben, können Sie diesen Code so ändern, dass er nur das Problem löst Datenbank einmal statt N + 1 mal (das N + 1 Problem ist ein bekannter Nachteil der Verwendung von Lazy Loading).

    
Michael Maddox 06.11.2009, 10:41
quelle
3

Der übliche Nachteil beim Lazy Loading ist, dass Sie im Vorfeld einen kleineren Treffer in der Datenbank machen, aber Sie werden langfristig mehr Treffer erzielen. Ohne Lazy Loading greifen Sie ein ganzes Objektdiagramm auf und saugen einen großen Datenblock gleichzeitig auf. Dies könnte möglicherweise zu Verzögerungen in Ihrer Benutzeroberfläche führen und wird daher oft davon abgeraten. Wenn Sie jedoch ein gemeinsames Objektdiagramm haben (nicht nur ein einzelnes Objekt - sonst wäre es egal!), Von dem Sie wissen, dass es häufig und von oben nach unten aufgerufen wird, ist es sinnvoll, es sofort abzulegen.

>

Wenn Sie beispielsweise ein Bestellverwaltungssystem ausführen, werden Sie wahrscheinlich nicht alle Zeilen jeder Bestellung oder alle Kundeninformationen auf einer Zusammenfassungsseite anzeigen. Lazy Loading verhindert dies.

Ich kann mir kein gutes Beispiel dafür vorstellen, es nicht ohne weiteres zu verwenden, aber ich bin mir sicher, dass es Fälle gibt, in denen Sie eine große Last eines Objektgraphen, zum Beispiel bei der Anwendungsinitialisierung, ausführen möchten Vermeiden Sie Verzögerungen bei der Verarbeitung weiter unten.

    
Harper Shelby 05.11.2009 17:34
quelle
2

Wenn Sie einen Webservice zwischen dem Client und dem Server verwenden, der den Datenbankzugriff mit nhibernate behandelt, kann es problematisch sein, lazy loading zu verwenden, da das Objekt serialisiert und über den Webservice und die nachfolgende Verwendung von "Objekten" weiter unten im Objekt gesendet wird Beziehung benötigt eine neue Reise zum Datenbankserver mit zusätzlichen Webservices. In solch einem Fall ist es vielleicht nicht so gut, das Lazy Loading zu verwenden. Ein Wort der Vorsicht, sei vorsichtig bei dem, was du holst, wenn du faul lädst, sein Weg ist einfach, dies nicht durch und durch zu denken und am Ende fast die ganze Datenbank zu holen ...

    
Jimmy 23.11.2009 00:51
quelle
1

Die kurze Version ist dies:

  1. Die Entwicklung ist einfacher, wenn Sie lazy loading verwenden. Sie durchqueren Objektbeziehungen auf natürliche Weise, und Sie bekommen, was Sie brauchen, wenn Sie danach fragen.
  2. Die Leistung ist im Allgemeinen besser, wenn Sie herausfinden, was Sie brauchen, bevor Sie danach fragen, und in einer Reise in die Datenbank danach fragen.

In den letzten Jahren haben wir uns auf schnelle Entwicklungszeiten konzentriert. Jetzt, wo wir eine solide App und Userbase haben, optimieren wir unseren Datenzugriff.

    
z5h 05.11.2009 17:32
quelle
0

Ich habe viele Leistungsprobleme bei der falschen Konfiguration des Ladeverhaltens in Hibernate gesehen. Die Situation ist ziemlich ähnlich mit NHibernate, denke ich. Meine Empfehlung ist, immer faule Relationen zu verwenden und dann eifrig abrufende Statements in der Abfrage zu verwenden - wie Fetch Joins -. Dadurch wird sichergestellt, dass Sie nicht zu viele Daten laden und viele SQL-Abfragen vermeiden können.

Es ist leicht, eine faule Affäre durch eine Abfrage zu erreichen. Es ist fast unmöglich umgekehrt.

    
Alois Reitbauer 26.11.2009 16:01
quelle