Tener problema de rendimiento extraño usando Hibernate 3.3.2GA detrás de la APP (y el resto de los paquetes incluidos en Hibernate JBoss 5.)APP (Hibernate) Nativo de consulta para la Declaración preparada LENTO
que estoy usando nativo de consulta y ensamblando SQL en una declaración preparada.
EntityManager em = getEntityManager(MY_DS);
final Query query = em.createNativeQuery(fullSql, entity.getClass());
El SQL tiene muchas uniones, pero en realidad es muy básico, con un solo parámetro. Me gusta:
SELECT field1, field2, field3 FROM entity left join entity2 on... left join entity3 on
WHERE stringId like ?
y la consulta se ejecuta en menos de un segundo en MSSQL Studio.
Si añado
query.setParameter(0, "ABC123%");
La consulta se detienen durante 9 segundos
2012-01-20 14:36:21 - TRACE: - AbstractBatcher.getPreparedStatement:(484) | preparing statement
2012-01-20 14:36:21 - TRACE: - StringType.nullSafeSet:(133) | binding 'ABC123%' to parameter: 1
2012-01-20 14:36:30 - DEBUG: - AbstractBatcher.logOpenResults:(382) | about to open ResultSet (open ResultSets: 0, globally: 0)
Sin embargo, si sólo se sustituye la "?" con el valor (lo que no es una declaración preparada, pero sólo una consulta SQL recta.
fullSql = fullSql.replace("?", "'ABC123%'");
la consulta completará en menos de un segundo.
que realmente preferiría que nos una declaración preparada (la entrada para los parámetros se está extrayendo de los datos del usuario) para prevenir ataques de inyección.
rastreando el punto lento en el código, llegué profundamente dentro del paquete jtds-1.2.2. La línea ofensiva parece ser SharedSocket línea 841 "getIn(). readFully (hdrBuf);" Nada realmente obvio allí ...
private byte[] readPacket(byte buffer[])
throws IOException {
//
// Read rest of header
try {
getIn().readFully(hdrBuf);
} catch (EOFException e) {
throw new IOException("DB server closed connection.");
}
Llegados a través de esta pila ...
at net.sourceforge.jtds.jdbc.SharedSocket.readPacket(SharedSocket.java:841)
at net.sourceforge.jtds.jdbc.SharedSocket.getNetPacket(SharedSocket.java:722)
at net.sourceforge.jtds.jdbc.ResponseStream.getPacket(ResponseStream.java:466)
at net.sourceforge.jtds.jdbc.ResponseStream.read(ResponseStream.java:103)
at net.sourceforge.jtds.jdbc.ResponseStream.peek(ResponseStream.java:88)
at net.sourceforge.jtds.jdbc.TdsCore.wait(TdsCore.java:3928)
at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1045)
at net.sourceforge.jtds.jdbc.TdsCore.microsoftPrepare(TdsCore.java:1178)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareSQL(ConnectionJDBC2.java:657)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java:776)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1808)
at org.hibernate.loader.Loader.doQuery(Loader.java:697)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.doList(Loader.java:2228)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2125)
at org.hibernate.loader.Loader.list(Loader.java:2120)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:312)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1722)
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:175)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:67)
Déjenme agregar jtds-1.2.2 a la pila de tecnología. He depurado a través de Hibernate en JTDS – javatestcase
intenté jtds-1.2.4, pero no me alegré ... – javatestcase
Cambiando a com.microsoft.sqlserver.jdbc.SQLServerDriver en realidad produce resultados idénticos ... Tengo que echar un vistazo a SQL Server, tal vez algo allí ... – javatestcase