2010-10-08 11 views
6

Szukałem bardzo powolnego zapytania SQL (pochodzącego z aplikacji Java wykorzystującej Hibernate wdrożony w JBoss 5.1). To konkretne zapytanie zwróciło około 10 000 rekordów, ale nadal trwało 40 lub więcej lat.Jakieś rozwiązanie problemu niewydolności Oracle TNS (wiele obietnic, opóźnień) z aplikacji Java?

Skończyłem węszyć ruchu z bazy danych (Wireshark ma narzędzie do wykrywania TNS) i znalazł coś nieoczekiwanego. Gdy dane pochodziły z serwera, każdy wiersz wyniku znajdował się w osobnym pakiecie TNS. Ponadto każdy pakiet TNS został potwierdzony przez klienta (tj. Serwer aplikacji) przed wysłaniem następnego z bazy danych. W przypadku rekordów 10K, istnieje 10K roundtrips, aby uzyskać pakiet i potwierdzić to. Wpływ na wydajność jest ogromny.

To jest bardzo nieefektywne. TCP pozwala na większe pakiety i ma wiele mechanizmów (przesuwne okna, opóźnione ACK), aby zmniejszyć opóźnienia i zwiększyć przepustowość. Jednak w tym przypadku jest to protokół TNS, który dodaje własne negocjacje.

Jeśli uruchomię to samo zapytanie od programisty SQL Oracle, nie widzę tego wzorca. Zapytanie kończy się za około 1/10 czasu, bez tysięcy podróży w obie strony.

Krótka wersja: protokół Oracle drut (TNS) wydaje się przekazać dane w jednym pakiecie za TNS zapytania wynik rzędu i wymaga każdy pakiet ma być potwierdzony przez klienta, zanim serwer wysyła następny.

Znalazłem informacje na ten temat [tutaj] [1] (przewiń w dół do sekcji "Parametry SDU i TDU w pliku tnsnames.ora").

I tak moje pytanie: czy można kontrolować zachowanie sterownika Oracle (używam 10.2.0.4.0), aby protokół TNS był bardziej wydajny? Ponownie jest to dość standardowa aplikacja J2EE wdrożona w JBoss.

Wielkie dzięki!

+0

Hej, dziękuję za głębokie Pytanie z pewnymi wskazówkami dla osób mających podobne sytuacje. Zagłosowano .. – TonyP

Odpowiedz

6

dostroić parametry w tnsnames.ora i listener.ora

SDU i TDU Aby ustawić wielkość wsadu do 100 dla bieżącej statystyki.

((OracleStatement)stmt).setRowPrefetch (100); 

Uwaga:

Ustawianie wielkości preselekcji może wpływać wykonywania aplikacji. Zwiększenie rozmiaru pobierania wstępnego spowoduje zmniejszenie liczby podróży w obie strony o , co zwiększy zużycie pamięci. Będzie to zależało od liczby i rozmiaru kolumn w zapytaniu oraz liczby oczekujących na powrót wierszy . Będzie to zależało także od załadowania maszyny klienta JDBC do pamięci i procesora . Optymalne rozwiązanie dla samodzielnego klienta Aplikacja będzie inna niż mocno obciążony serwer aplikacji . szybkości i opóźnienia połączenia sieciowego powinny być consideredconnection należy również rozważyć

(z Oracle Database JDBC Developer's Guide and Reference)

dostępne właściwości połączenia here.

Zobacz także Oracle UCP.

+0

Dzięki, po przeszukaniu wstępnym google dla wiersza znalazłem następujący komunikat: "Standardowy JDBC odbiera zestaw wyników po jednym wierszu naraz, a każdy wiersz wymaga podróży w obie strony do bazy danych" na http://download.oracle.com/docs/cd/ B19306_01/java.102/b14355/oraperf.htm, który wyjaśnia, co widziałem. Hmm ... czy można ustawić na poziomie źródła danych? Lista parametrów pod adresem http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html nie zawiera ustawienia wstępnego pobierania. – wishihadabettername

+1

W międzyczasie znalazłem właściwość sterownika (defaultRowPrefetch) na http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/urls.htm#i1006362 – wishihadabettername

+0

Czy używasz UCP? http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html – oluies

3

Spróbuj zwiększyć rozmiar pobierania dla twojego obiektu sytemu.

myślę domyślnym jest 10, więc można spróbować zacząć 100.

 
Statement stmt = connection.createStatement(); 
stmt.setFetchSize(100); 
ResultSet rs = stmt.executeQuery("SELECT ..."); 
+0

Zwiększenie rozmiaru pobierania poprawiło sytuację, wypełniając pakiety TCP. – wishihadabettername

Powiązane problemy