2012-08-28 7 views
5

Używam Spring NamedParameterJdbcTemplate do pobierania niektórych wartości z tabeli. Z jakiegoś powodu kwerenda działa bardzo wolno w mojej aplikacji Java, w przeciwieństwie do uruchamiania tego samego zapytania w SQL Management Studio. Zauważyłem także w profilerze, że przygotowane oświadczenia nie są ponownie wykorzystywane. Jeśli wielokrotnie uruchamiam to samo zapytanie w mojej aplikacji JAVA, widzę, że wykonywane są różne gotowe instrukcje. Nie wiem więc, dlaczego oświadczenia nie są ponownie wykorzystywane. Czy wydajność jest powolna, ponieważ w moim zapytaniu używam klauzuli IN?Spring NamedParameterJDBCTemplate ponowne użycie gotowych instrukcji

Oto mój przykładowy kod Java

StringBuilder vQuery = new StringBuilder(); 
vQuery.append(" SELECT SUM(Qty) FROM vDemand"); 
vQuery.append(" WHERE ProductID = :ProductID"); 
vQuery.append(" AND [Date] >= :StartDate AND [Date] <= :EndDate"); 
vQuery.append(" AND CustomerID IN (:CustomerID)"); 

MapSqlParameterSource vNamedParameters = new MapSqlParameterSource(); 
vNamedParameters.addValue("ProductID", aProductID); 
vNamedParameters.addValue("CustomerID", aCustomerlIDs); 
vNamedParameters.addValue("StartDate", aDate, Types.TIMESTAMP); 
vNamedParameters.addValue("EndDate", aDate, Types.TIMESTAMP); 

int vTotalQuantity = this.getNamedParameterJdbcTemplate().queryForInt(vQuery.toString(), vNamedParameters); 
return vTotalQuantity; 

Odpowiedz

9

Patrząc na kod źródłowy sprężyny NamedParameterJdbcTemplate, analizuje swoją SQL w strukturze ParsedSql, a następnie zastępuje swoich parametrów nazwanych ze znakami zapytania, a następnie buduje PreparedStatement i wypełnia go swoimi parametrami.

Buforuje wpisy ParsedSql, ale zawsze buduje nowe PreparedStatements, więc ostatecznie nie są one ponownie wykorzystywane na poziomie sterownika JDBC.

PreparedStatement ma dwie zalety w stosunku do regularnej Statement:

  1. dodać parametry do SQL przy użyciu metody zamiast robić to wewnątrz samego zapytania SQL. Dzięki temu unikasz ataków typu SQL injection, a także pozwalasz kierowcy wykonywać konwersje typu.

  2. Tak jak powiedziałeś, ten sam PreparedStatement może być wywoływany z różnymi parametrami, a silnik bazy danych może ponownie wykorzystać plan wykonywania zapytań.

Wygląda na to, że NamedParameterJdbcTemplate pomaga w pierwszej korzyści, ale nie robi nic dla tej ostatniej.

+0

Dzięki. Dziwna rzecz, którą widzę jest nawet dla pojedynczego zapytania, czas wykonywania jest około 50 razy więcej niż czas pracy w studio zarządzania serwerami sql. Postaram się pozbyć parametrów nazwanych i zobaczyć, czy prosty sql rozwiązuje problem. dzięki jeszcze raz. – user320587

+2

Myślę, że to inny problem, sprawdź konfigurację sterownika jdbc. Utwórz nowy projekt ze sterownikiem i główną metodą, która wykonuje tylko zapytanie, zwykły sql. 50 razy wolniej jest za dużo. – Luciano