2009-11-05 13 views
8

Większość tego, co słyszę o ładowaniu przez NHibernate, polega na tym, że lepiej go używać, niż go nie używać. Wydaje się, że uzasadnione jest zminimalizowanie dostępu do bazy danych w celu zmniejszenia "wąskich gardeł". Ale niewiele rzeczy przychodzi bez kompromisów, na pewno nieznacznie ogranicza projekt, zmuszając cię do posiadania właściwości. Ale zauważyłem również, że niektórzy programiści wyłączają leniwy ładunek na niektórych często używanych obiektach.Kiedy należy unikać używania funkcji ładowania w systemie NHibernate?

To sprawia, że ​​zastanawiam się, czy istnieją pewne określone sytuacje, w których wydajność dostępu do danych jest zraniona przy użyciu leniwego ładowania.

Zastanawiam się więc, kiedy iw jakich sytuacjach powinienem unikać leniwego ładowania jednego z moich obiektów przechowywanych przez NHibernate?

Czy minusem leniwego ładowania jest tylko dodatkowy czas przetwarzania, czy też można zaimplementować ładowanie w trybie lazy-load również w celu wydłużenia czasu dostępu do danych (na przykład poprzez dodatkowe dodatkowe wizyty w bazie danych w obie strony)?

Dzięki!

Odpowiedz

19

Istnieje wyraźna kompromitacja wydajności pomiędzy chętnymi i leniwymi obiektami ładującymi z bazy danych.

Jeśli korzystasz z szybkiego ładowania, możesz zassać mnóstwo danych w jednym zapytaniu, które możesz następnie buforować. Jest to najczęściej spotykane podczas uruchamiania aplikacji. Zajmujesz się konsumpcją pamięci podczas podróży w obie strony.

Jeśli używasz leniwego ładowania, wysysasz minimalną ilość danych w jednym zapytaniu, ale w każdej chwili potrzebujesz więcej informacji związanych z tymi początkowymi danymi, które wymagają więcej zapytań do bazy danych, a trafienia bazy danych są często wąskie gardło w większości zastosowań.

Ogólnie rzecz biorąc, zawsze chcesz pobrać dokładnie te dane, których potrzebujesz do całego "unit of work", nie więcej, nie mniej. W niektórych przypadkach możesz nie wiedzieć dokładnie, czego potrzebujesz (ponieważ użytkownik pracuje przez kreatora lub coś podobnego) iw takim przypadku prawdopodobnie ma sens leniwy ładunek w trakcie pracy.

Jeśli korzystasz z ORM i koncentrujesz się na szybkim dodawaniu funkcji i wrócisz i zoptymalizujesz wydajność później (co jest bardzo powszechnym i dobrym sposobem na robienie rzeczy), to leniwy ładowanie jest domyślnym sposobem poprawnego działania . Jeśli później (poprzez profilowanie/analizę wydajności) odkryjesz, że masz jedną kwerendę, aby uzyskać obiekt, a następnie N zapytań, aby uzyskać N obiektów związanych z tym oryginalnym obiektem, możesz zmienić ten fragment kodu, aby użyć szybkiego ładowania, aby tylko uderzyć w baza danych raz zamiast N + 1 razy (problem N + 1 jest dobrze znaną wadą korzystania z leniwego ładowania).

+0

Ale jeśli zaczniesz używać lazyloading po tym, jak projekt stanie się tak ogromny, to spóźnisz się, aby zmienić wiele rzeczy. Myślę, że najlepszym sposobem jest dowiedzieć się, jakie dane należy pobrać z bazy danych w jednym zapytaniu. w tym podejściu można później buforować te obiekty, ale nie można buforować tych obiektów, które mają lazyloading. – Meysam

1

Krótka wersja jest taka:

  1. Development jest prostsze, jeśli używasz leniwy załadunku. Po prostu przechodzisz przez relacje między obiektami naturalną metodą OO, a otrzymujesz to, czego potrzebujesz, kiedy o to poprosisz.
  2. Wydajność jest ogólnie lepsza, jeśli wymyślisz, czego potrzebujesz, zanim o to poprosisz, i poproś o nią w trakcie jednej podróży do bazy danych.

Od kilku lat koncentrujemy się na szybkich czasach rozwoju. Teraz, gdy mamy solidną aplikację i bazę użytkowników, optymalizujemy nasz dostęp do danych.

+2

Łączna wydajność może być lepsza, ale czasami duże obciążenia graficzne obiektów mogą wpływać na * pozorną * wydajność, która czasami może być większa dla użytkowników. –

+1

Doskonały punkt. Załaduj podstawy. Pokaz. Ajax w przemierzał wartości w razie potrzeby. (na przykład). – z5h

3

Zwykle kompromisem dla leniwego ładowania jest to, że robisz mniejsze trafienie w bazie danych z góry, ale na koniec robisz więcej trafień w dłuższej perspektywie. Bez leniwego ładowania, pobierzesz cały wykres obiektów z przodu, zasysając dużą porcję danych jednocześnie. Może to potencjalnie powodować opóźnienia w interfejsie użytkownika, dlatego często jest odradzane. Jeśli jednak masz wspólny wykres obiektów (nie tylko pojedynczy obiekt - w przeciwnym razie nie miałoby to znaczenia!), O którym wiesz, że będzie często odwiedzany, a od góry do dołu, to rozsądne, aby go pobrać na raz.

Na przykład, jeśli robisz system zarządzania zamówieniami, prawdopodobnie nie wyciągniesz wszystkich wierszy każdego zamówienia lub wszystkich informacji o kliencie na ekranie podsumowania. Leniwe ładowanie zapobiega temu zjawisku.

Nie mogę wymyślić dobrego przykładu, aby nie używać go od ręki, ale jestem pewien, że są przypadki, w których chciałbyś zrobić duże obciążenie grafu obiektu, powiedzmy, przy inicjalizacji aplikacji, w celu aby uniknąć opóźnień w przetwarzaniu w dalszej kolejności.

2

Jeśli używasz usługi sieciowej między klientem a serwerem obsługującym dostęp do bazy danych za pomocą nhibernate, może to być problematyczne przy użyciu leniwego ładowania, ponieważ obiekt będzie serializowany i wysyłany przez usługę internetową, a następnie użycie "obiektów" w dalszej części relacja obiektowa wymaga nowej podróży do serwera bazy danych przy użyciu dodatkowych usług internetowych. W takim przypadku może nie być zbyt dobry przy użyciu leniwego ładowania. Jedna uwaga, bądź ostrożny w tym, co przyniosłeś, jeśli położysz leniwy ładunek, jego sposób na łatwe, aby nie pomyśleć przez cały czas i kończy się pobieranie prawie całej bazy danych ...

0

Widziałem wiele problemów z wydajnością wywodzi się z błędnej konfiguracji zachowania podczas ładowania w trybie hibernacji. Sytuacja wygląda podobnie w przypadku NHibernate. Moim zaleceniem jest zawsze używać leniwych relacji, a następnie używać chętnych do pobierania statystyk w zapytaniu - takich jak połączenia pobierania -. To zapewnia, że ​​nie ładujesz się do wielu danych i możesz uniknąć wielu zapytań SQL.

Łatwo jest zrobić leniwą wersję chętną przez zapytanie. Jest prawie niemożliwe na odwrót.

Powiązane problemy