Przechowywany proc działa wolniej o 30% przez Javę niż działa bezpośrednio w bazie danych

Używam Java 1.6, JTDS 1.2.2 (również bezskutecznie próbowałem 1.2.4) i SQL Server 2005, aby utworzyć CallableStatement, aby uruchomić procedurę składowaną (bez parametrów). Widzę opakowanie Java uruchamiające tę samą procedurę przechowywaną 30% wolniej niż przy użyciu SQL Server Management Studio. Uruchomiłem program profilujący MS SQL i nie ma dużej różnicy we / wy między tymi dwoma procesami, więc nie sądzę, że jest to związane z buforowaniem planu zapytań.

Zapisany proc nie pobiera żadnych argumentów i nie zwraca żadnych danych. Używa kursora po stronie serwera do obliczenia wartości potrzebnych do wypełnienia tabeli.

Nie widzę, jak wywołanie przechowywanego proc z Javy powinno dodać 30% narzutu, z pewnością jest to tylko potok do bazy danych, który jest wysyłany przez SQL, a następnie baza danych go wykonuje .... Czy baza danych może dawać Java aplikacja inny plan zapytania?

Wysłałem do obufora MSDNoraz fora JTDS sourceforge (temat: „przechowywane proc wolniej w JTDS niż bezpośrednio w DB”) Zastanawiałem się, czy ktoś ma jakieś sugestie, dlaczego tak się dzieje?

Z góry dziękuję,

-James

(N.B. Nie bój się, zgromadzę tutaj wszystkie odpowiedzi, które otrzymam na innych forach, gdy tylko znajdę rozwiązanie)

Fragment kodu Java:

sLogger.info("Preparing call...");
stmt = mCon.prepareCall("SP_WB200_POPULATE_TABLE_limited_rows");
sLogger.info("Call prepared.  Executing procedure...");
stmt.executeQuery();
sLogger.info("Procedure complete.");

Uruchomiłem program profilujący sql i znalazłem następujące:

Aplikacja Java: CPU: 466,514 Odczyty: 142 478 387 Pisanie: 284 078 Czas trwania: 983,796

SSMS: CPU: 466,973 Odczyty: 142,440,401 Pisanie: 280,244 Czas trwania: 769 851

(Oba z DBCC DROPCLEANBUFFERS działają przed profilowaniem i oba generują prawidłową liczbę wierszy)

Więc mój wniosek jest taki, że oboje wykonują te same odczyty i piszą, po prostu sposób, w jaki to robią, jest inny, co myślicie?

Okazuje się, że plany kwerend różnią się znacznie dla różnych klientów (klient Java aktualizuje indeks podczas wstawiania, które nie znajduje się w szybszym kliencie SQL, również sposób łączenia jest inny (zagnieżdżone pętle Vs. zbierać strumienie, zagnieżdżone pętle skanuje indeks Vs, argh!)). Zupełnie dlaczego tak jest, nie wiem jeszcze (powrócę, gdy dojdę do sedna)

Epilog

Nie mogłem tego zrobić poprawnie. Próbowałem homogenizacji właściwości połączenia (arithabort, ansi_nulls itp.) między klientami Java i Mgmt Studio. Skończyło się na tym, że dwóch różnych klientów miało bardzo podobne plany zapytań / wykonania (ale nadal z różnymi rzeczywistymi planami). Opublikowałem podsumowanie tego, co znalazłemfora MSDN SQL Server ponieważ znalazłem różną wydajność nie tylko między klientem JDBC a studiem zarządzania, ale także między własnym klientem wiersza poleceń firmy Microsoft, SQLCMD, sprawdziłem też kilka bardziej radykalnych rzeczy, takich jak ruch sieciowy, lub zawijając zapisany proc w innym zapisanym proc, tylko dla uśmiecha się.

Mam wrażenie, że problem leży gdzieś w sposobie wykonywania kursora, i to w jakiś sposób spowodowało zawieszenie procesu Java, ale dlaczego inny klient powinien wywołać to inne zachowanie blokowania / oczekiwania, gdy nic innego nie działa a ten sam plan wykonania jest nieco poza moimi umiejętnościami (nie jestem DBA!).

W rezultacie zdecydowałem, że 4 dni to wystarczająco dużo czasu, aby zmarnować coś takiego, więc niechętnie koduję to (jeśli mam być szczery, procedura przechowywana wymagała ponownego kodowania, aby była bardziej przyrostowa niż re - i tak obliczaj wszystkie dane w każdym tygodniu) i zaznacz je jednym słowem. Pozostawię pytanie otwarte, wielkie dzięki dla wszystkich, którzy wkładają kapelusz na ring, to wszystko było przydatne, a jeśli ktoś wymyśli coś jeszcze, z przyjemnością usłyszę więcej opcji ... i jeśli ktoś znajdzie w tym poście jako rezultat zobaczenia tego zachowania w ich własnym środowisku, mam nadzieję, że jest tu kilka wskazówek, które możesz wypróbować samodzielnie, i miej nadzieję, że zobaczymy je dalej niż my.

Jestem już gotowy na mój weekend!

-James

questionAnswers(7)

yourAnswerToTheQuestion