2012-05-13 7 views
5

Używam obsługi Hibernate dla strategii dziedziczenia TABLE_PER_CLASS. Funkcjonalność jest mądra, działa dobrze. Ilekroć zapytania polimorficzny jest wydawana Hibernacja generuje SQL zawierający „UNION ALL” dla moich dwóch konkretnych klas A & B. generowane SQL ma następujący format:Jak przezwyciężyć problemy z wydajnością spowodowane przez wygenerowany SQL podklasy związków w Hibernate

select C1, C2, C3 from (
    select C1, C2, C3 from ClassA 
    union all 
    select C1, C2, C3 from ClassB 
) 
where 
    C1 == <value> 
order by C2 
limit 100 

Problem ten podejście cierpi na bardzo złych wyników na DB bok. Uwzględnienie kolumny C1 jest wspólną własnością ClassA i ClassB (pochodną abstrakcyjnego elementu nadrzędnego). Hibernate może wstawić klauzulę where w obu subselekcjach i znacznie poprawić wydajność. Na przykład:

select C1, C2, C3 from ( 
    select C1, C2, C3 from ClassA where C1 == <value> 
    union all 
    select C1, C2, C3 from ClassB where C1 == <value> 
) 
order by C2 
limit 100 

Niektóre optymalizacji można również zrobić na limicie. Używam interfejsu API kryteriów Hibernuj w mojej warstwie DAO.

Nie można użyć przechwytującego, onPrepareStatment(), ponieważ argumenty nie są widoczne. Używanie partycji i ewentualnie innych opcji w bazie danych jest obecnie poza zakresem, ponieważ chcemy uniknąć optymalizacji bazy danych na tym etapie pracy.

Każdy pomysł, jak zmanipulować hibernację, aby poprawić wydajność?

+0

Czy możesz być bardziej zrozumiały - daj zapytanie SQL wygenerowane teraz i wariant, który spowoduje lepszą wydajność. – gkamal

+0

Co to jest bazowa baza danych? Przypuszczam, że to nie byłaby Oracle, ponieważ zwykle przesuwa predykaty na podselekcje i na związki ... Czy 'C1' ma odpowiedni indeks w obu tabelach? –

+0

C1 mają indeks na obu tabelach. Możemy w końcu obsługiwać wiele DB, w tym Derby (Pure java). W związku z tym obecnie skupiamy się na zdefiniowaniu schematu, który zapewni najlepszą wydajność dla wszystkich baz danych. – user1392212

Odpowiedz

0

Chciałbym wysokiej wydajności między bazami danych, niż zalecałbym nie używać table-pr-class i wielu lub ogromnych zapytań polimorficznych. Kolumna dyskryminacyjna byłaby zazwyczaj lepsza.

Pamiętaj, że możesz łączyć tablicę pr-class z dyskretnymi kolumnami, jeśli masz więcej niż dwa poziomy w hierarchii klas.

+0

Dzięki za odpowiedź. Mimo to staram się unikać ogromnego stołu, który w 99% przypadków 90% jego danych nie jest potrzebne, dzieląc tabele. – user1392212

Powiązane problemy