2010-12-09 29 views
57

He estado leyendo algunos torres, pero todavía estoy confundido. ¿Por qué? porque las diferencias que has mencionado no se relacionan con el rendimiento. están relacionados con el uso fácil. (Objetc (criterios) y SQL (hql)). Pero me gustaría saber si los "criterios" son más lentos que hql por alguna razón.Hibernate Criteria vs HQL: ¿qué es más rápido?

leí esto en otro anwers

"Hay una diferencia en términos de rendimiento entre HQL y criteriaQuery, cada vez que usted enciende una consulta mediante criteriaQuery, se crea un nuevo alias para el nombre de la tabla que no refleja en la última caché consultada para cualquier DB. Esto lleva a una sobrecarga de compilación del SQL generado, lo que lleva más tiempo para su ejecución ". por Varun Mehta.

Esto está muy cerca PERO! Lo leí en otro sitio web (http://gary-rowe.com/agilestack/tag/hibernate/) Este ya no es el caso con Hibernate 3.3 y versiones superiores (por favor, lea esto: 9) Hibernate es lento porque el SQL generado por el La interfaz de criterios no es consistente)

He hecho algunas pruebas para descubrir las diferencias, pero ambas generan qry's y no cambia el alias de la tabla.

Estoy muy confundido. Si alguien conoce el motivo principal, ¿podría ayudarnos? Gracias

Respuesta

2

Principalmente prefiero las Consultas de criterios para las consultas dinámicas. Por ejemplo, es mucho más fácil agregar un poco de orden dinámicamente o dejar algunas partes (por ejemplo, restricciones) dependiendo de algún parámetro.

Por otro lado, estoy usando HQL para consultas estáticas y complejas, porque es mucho más fácil de entender/leer HQL. Además, HQL es un poco más poderoso, creo, p. para diferentes tipos de unión.

JPA and Hibernate - Criteria vs. JPQL or HQL

+2

Los criterios pueden hacer la mayoría de los tipos de combinación que HQL puede hacer, aunque a veces es un poco incómodo o difícil de entender (al menos en mi opinión). ¡Absolutamente correcto acerca de que HQL es más fácil de leer! –

+1

Por cierto, votaría por tu respuesta ... pero en realidad no respondiste la pregunta de kcobuntu. –

+23

Si va a copiar la respuesta de otra persona, al menos debería mencionarla. Enlace a la respuesta original: http://stackoverflow.com/a/197496/980103 –

124

yo soy el tipo que escribió el traductor consulta de Hibernate 3 en el año 2004, por lo que saben algo acerca de cómo funciona.

Los criterios, en teoría, deberían tener menos sobrecarga que una consulta HQL (excepto para las consultas con nombre, a las que llegaré). Esto se debe a que Criteria no necesita analizar nada. Las consultas HQL se analizan con un analizador basado en ANTLR y luego el AST resultante se convierte en SQL. Sin embargo, con HQL/JPAQL puede definir consultas con nombre, donde el SQL se genera cuando se inicia SessionFactory. En teoría, las consultas con nombre tienen menos sobrecarga que Criteria.

Por lo tanto, en términos de gastos generales de SQL generación tenemos:

  1. Named HQL/JPAQL consultas - la generación de SQL sucede sólo una vez.
  2. Criterios: no es necesario analizar antes de generar.
  3. (sin nombre) HQL/JPAQL Query - Parse, luego generar.

Dicho esto, la elección de una técnica de consulta basada en la sobrecarga de analizar y la generación de SQL es probablemente un error en mi opinión. Esta sobrecarga suele ser muy pequeña en comparación con la realización de una consulta real en un servidor de base de datos real con datos reales. Si esta sobrecarga realmente aparece al crear el perfil de la aplicación, entonces tal vez debe cambiar a una consulta con nombre.

Estas son las cosas que considerar al decidir entre Criteria y HQL/JPAQL:

  • En primer lugar, usted tiene que decidir si está bien con tener una dependencia en Hibernate API propietaria en tu codigo. JPA no tiene Criteria.
  • Los criterios son realmente buenos para manejar muchos parámetros de búsqueda opcionales, como los que puede encontrar en una página web típica con un "formulario de búsqueda" de parámetros múltiples. Con HQL, los desarrolladores tienden a virar en donde las expresiones de cláusula con StringBuilder (¡evite esto!). Con Criteria, no necesita hacer eso. Hardik publicó opiniones similares.
  • HQL/JPAQL puede usarse para la mayoría de las otras cosas, porque el código tiende a ser más pequeño y más fácil de entender para los desarrolladores.
  • Las consultas muy frecuentes se pueden convertir en consultas con nombre si utiliza HQL. Prefiero hacer esto más tarde, después de algunos perfiles.
+0

'JPA no tiene Criteria'? – destan

+3

@destan A partir de JPA 2.x, lo hace. IIRC, JPA 1.x no. –

+0

@JoshuaDavis Excelente explicación. Solo quiero saber por qué debemos evitar usar StringBuilder para construir HQL. ¿Qué hacer con los parámetros opcionales, por ejemplo? –

6

Estoy trabajando en millones de registros. Descubrí que HQL es mucho más rápido que Criteria. Los criterios tienen un rendimiento mucho mayor.

Si está trabajando con muchos datos, vaya a HQL.

+2

Esto no tiene mucho sentido para mí.Si tiene un conjunto de datos realmente grande, la mayor parte del tiempo se gasta en esperar que la base de datos procese la consulta. El tiempo que lleva generar el SQL de HQL o de Criteria no es importante en ese caso. El único momento en que se utilizan consultas con nombre JPAQL frente a JPAQL 'directo' frente a Criteria es cuando se realiza la misma consulta * muchas * veces. El tamaño del conjunto de datos no importa en absoluto. –

+1

Puede ser que no haya usado Criteria de la manera correcta. ¿O ha creado un nuevo objeto Criteria Query para cada uno de sus millones de registros? – vinodn

3

Otras ventajas creo que para los Criterios más de HQL:

escritura HQL hace que el código desordenado. Ya no parece escribir código limpio orientado a objetos.

Al escribir Consultas de criterios, IDE nos sugiere con Intellisense, por lo que hay menos posibilidades de cometer errores, excepto cuando escribimos algo así como nombres de variables entre comillas dobles.

1

Tienes razón y no. La lista de resultados se obtiene de la base de datos o el caché con la clase org.hibernate.loader.Loader. Cuando la memoria caché no está habilitada, la instrucción preparada se genera utilizando el objeto Dialect que se crea en SessionFactoryImp. Entonces, las declaraciones se inicializan por lista de llamadas. Además, la consulta de bajo nivel se genera automáticamente. Básicamente, es una ayuda, pero puede haber un caso en el que una consulta específica será más efectiva cuando se escriba manualmente.

Cuestiones relacionadas