Od kilku dni borykam się z zapytaniem o hibernację przeciwko bazie danych Oracle. Coś podobnego do tego, które służy do podawania rekordów do siatki.Hibernate sparametryzowane zapytanie sql wolne i aktywne sesje oracle
SELECT
fields
FROM
tables and JoinedTables
WHERE
Field1 >= :value1
AND Field2 = :value2
AND Field3 = :value3
Order By MaintTable.Id Desc
Stosowanie tego podejścia w wiosennej wersji Java + Hibernacja 4.2.
SQLQuery query = (SQLQuery) session.createSQLQuery(querySql)
.addEntity(CertificateViewEnt.class)
.setParameter("value1", firstCertificateRecordDate)
.setParameter("value2", certType.toUpperCase())
.setParameter("value3", deleted? 1:0);
Każde przefiltrowane pole jest poprawnie indeksowane i tworzy indeks funkcji na Maintable.Id Descendent, aby poprawić wydajność.
Na początku myślałem, że to basen sesji/połączenia nie są prawidłowo zarządzane, więc zmieniłem na StatelessSession i dodaj session.close():
query.setCacheable(false)
.setTimeout(30)
.setReadOnly(true);
...
...
//Pagination
query.setMaxResults(rows);
query.setFirstResult(HelperMethod(page, rows));
result = (List<CertificateViewEnt>) query.list();
session.close();
return result;
To nie rozwiązany. Kwerenda działa kilka razy OK, ale z jakiegoś nieznanego powodu i przy użyciu wartości, które zostały wcześniej uruchomione z sukcesem, zawiesza się, pozostawia sesję otwartą w Oracle (status = AKTYWNY) i kończy się niepowodzeniem po przekroczeniu limitu czasu. To samo zapytanie jest uruchamiane przeciwko Oracle na dowolnym kliencie SQL i dziesiątki razy z wszystkimi możliwymi kombinacjami wykonywanych paramerów z ekstremalną wydajnością, około 400ms, dla 10 rekordów naraz.
Po przeczytaniu kilka artykułów tutaj i tam, LINK1 [Slow performance on Hibernate + Java but fast when I use TOAD with the same native Oracle query Link2: [query hangs oracle 10g
I supected słabo QueryPlan używany przez Hibernate i postanowił usunąć wszystkie filtry wykorzystaniem parametrów związanych i również nie rozwiązany, choć było trochę lepiej. Po chwili powiesił po przeniesieniu do innych stron jak strona 1, 2,3,4, ...
Po tym wszystkim, że ja podejrzany o SQL generowany przez metody hibernacji za
query.setMaxResults(rows)
query.setFirstResult(SomeHelperMethod(page, rows));
Ponieważ piła w dzienniku, że zostały przekazane jako parametry wiązania do Oracle.
...
Order By Certificado.Id Desc) row_
where rownum <= ?)
where rownum_ > ?
Widziałem też ten w ślad Log
2015-09-15 14:09:53 TRACE QueryPlanCache:200 - Located native-sql query plan in cache (SELECT /*+ INDEX(
a to:
2015-09-15 14:09:53 TRACE BasicBinder:84 - binding parameter [2] as [VARCHAR] - E
2015-09-15 14:09:53 DEBUG Loader:2031 - bindNamedParameters() 0 -> deleted [3]
2015-09-15 14:09:53 TRACE BasicBinder:84 - binding parameter [3] as [INTEGER] - 0
2015-09-15 14:09:53 TRACE Loader:1931 - Bound [7] parameters total
/*
SLOW here !!! Around 3 secs when query runs in ~0,300 secs via SQL client.
And ACTIVE sessions are left running in Oracle.
*/
2015-09-15 14:09:56 TRACE JdbcCoordinatorImpl:397 - Registering result set [[email protected]]
2015-09-15 14:09:56 TRACE Loader:943 - Processing result set
końcu musiałem porzucić wszystkie wiążą params Hibernate i wdrożone obliczeń zwyczaj paginacji i napisał wszystkie SQL aby pobrać wiersze strony i poprawnie obsługuje sesje db.
Tak, moje pytanie brzmi: Co to jest hibernacja robiąca sceny, które uniemożliwiają uruchomienie zapytania w wyniku działania bazy danych? Czy jest jakiś znany problem z zapytaniami o parametry powiązania?
Naprawdę nie lubię pisać całego kodu SQL i wymuszać ciężkie parsowanie tego SQL, gdy mam parametry wiązania.
Kilka uwag na temat środowiska: Tomcat i Oracle znajdują się na tym samym hoście.Więc połączenie sieciowe nie jest problemem
wersja 4.2.15 Hibernate końcowy
tabela ma około 300k regionalnych wspólnot gospodarczych w bazie dev (1,5m na produkcji) i pokazuje strony 10, 20, 50 REC naraz , posortowane według klucza głównego Desc (wygenerowana sekwencja)
Mam nadzieję, że niektórzy eksperci Hibernate mogą mi pomóc w tym zakresie, aby nadal móc ufać zapytaniom Hibernate w dużych projektach bazodanowych. Z góry dzięki.
Mając ten sam problem. W środowisku MySQL Workbench zapytanie trwa 0 ms. W stanie hibernacji trwa to 1500ms. –
Usuń wszystkie parametry Hibernate i samodzielnie zbuduj zapytanie SQL ze wszystkimi parametrami ustawionymi w ciągu SQL. To zadziałało dla mnie. Tak jak to było w przypadku starej szkoły JDBC. –
Dzięki za cynk. Zdecydowanie warto spróbować! –