2012-08-28 24 views
5

Estoy utilizando Spring NamedParameterJdbcTemplate para recuperar algunos valores de una tabla. Por alguna razón, la consulta se ejecuta muy lento en mi aplicación Java en lugar de ejecutar la misma consulta en SQL Management Studio. También noté que en el generador de perfiles, las declaraciones preparadas no se reutilizan. Si ejecuto la misma consulta en mi aplicación JAVA varias veces, veo que se ejecutan diferentes declaraciones preparadas. Entonces, no estoy seguro de por qué las declaraciones no se vuelven a utilizar. ¿El rendimiento es lento porque estoy usando una cláusula IN en mi consulta?Spring NamedParameterJDBCTemplate reutilización de las declaraciones preparadas

Aquí está mi ejemplo de código 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; 

Respuesta

9

Si examina el código fuente de la primavera de NamedParameterJdbcTemplate, analiza su SQL en una estructura ParsedSql, y luego reemplaza sus parámetros con nombre con signos de interrogación, entonces construye la PreparedStatement y lo llena con tus parámetros.

Almacena en caché las entradas ParsedSql, pero siempre crea el nuevo PreparedStatements, por lo que, en última instancia, no se vuelven a utilizar en el nivel del controlador JDBC.

Un PreparedStatement tiene dos ventajas sobre un habitual Statement:

  1. agregar parámetros al SQL utilizando métodos en lugar de hacerlo dentro de la propia consulta SQL. Con esto evitas los ataques de inyección SQL y también permites que el controlador haga conversiones tipo por ti.

  2. Como dijo, se puede llamar al mismo PreparedStatement con diferentes parámetros, y el motor de la base de datos puede reutilizar el plan de ejecución de la consulta.

Parece que NamedParameterJdbcTemplate le ayuda con la primera ventaja, pero no hace nada por este último.

+0

Gracias. Lo extraño que veo es que, incluso para una sola consulta, el tiempo de ejecución es aproximadamente 50 veces mayor que el tiempo de ejecución en el estudio de administración de servidor sql. Trataré de deshacerme de los parámetros de Nombre y ver si un sql directo soluciona el problema. gracias de nuevo. – user320587

+2

Creo que es un problema diferente, verifique la configuración de su controlador jdbc. Cree un nuevo proyecto con el controlador y un método principal que solo ejecute la consulta, sql simple. 50 veces más lento es demasiado. – Luciano

Cuestiones relacionadas