2009-08-25 11 views
13

Tengo un objeto de dominio Hibernate que se carga en diferentes partes de la aplicación. A veces es conveniente cargar perezosas todas las asociaciones y otras es mejor cargar todo en una sola combinación. Como un compromiso afortunadamente feliz que he encontrado:Hibernate: batch_size? Segundo nivel de caché?

Al usar la recuperación por lotes, Hibernate puede cargar varios proxies no inicializados si se accede a un proxy. La búsqueda por lotes es una optimización de la estrategia de búsqueda de selección perezosa.

hibernate.default_batch_fetch_size:

Uso de la recuperación en lotes, Hibernate puede cargar varios proxies sin inicializar Si se accede a un proxy. La recuperación por lotes es una optimización de la estrategia de recuperación de selección diferida .

También veo:

hibernate.jdbc.fetch_size:

Un valor distinto de cero determina el JDBC traiga tamaño (llamadas Statement.setFetchSize()).

Bueno, ¿es Hibernate lo suficientemente inteligente como para buscar en el caché de segundo nivel cuando se realiza la búsqueda por lotes? es decir, ¿se obtiene una para la llamada inicial a la asociación y luego las siguientes X llamadas golpean la memoria caché? De esa forma puedo tener la carga lenta que deseo pero también presionar el caché a menudo para las transacciones más grandes.

Si todo el contenido de la colección ya está contenido en la memoria caché, ¿seguirá ejecutando las consultas al acceder a la colección?

Gracias.

+0

Ahora esto es algo que también me gustaría saber la respuesta. – Zoidberg

+1

Marque mi pregunta :-) – davidemm

Respuesta

6

Investigué mucho hoy y pude encontrar una respuesta a mi propia pregunta. Estaba mirando a través del código de Hibernate y el flujo se ve así:

¿Se ha inicializado la recopilación?

  • ¿No? Hacer una búsqueda por lotes (los elementos obtenidos por batch-fetch se colocan en la memoria caché)
  • Sí? Busque en la memoria caché el artículo en particular, si no está allí haga una búsqueda por lotes.

Así que si el elemento de la colección que está buscando se encuentra en la caché, entonces el lote-fetch no sucede. Si el elemento NO se encuentra en la memoria caché de segundo nivel, se produce la recuperación de lote, PERO hará una búsqueda de elementos por lotes INDEPENDIENTEMENTE de si los elementos por lotes están en la memoria caché.


----- ----- Ejemplo 1

Lo bueno:

(Tres elementos de una colección - Tamaño de lote de 3) La primera vez:

  • collection.getItem (0) - Sin caché | batch-fetch 3 artículos
  • colección.getItem (1) - Cargado en por lotes-fetch
  • collection.getItem (2) - cargado en por lotes-fetch

Ahora, en otro lugar, más tarde en el tiempo:

  • colección. getItem (0) - Cache Hit
  • collection.getItem (1) - Cache Hit
  • collection.getItem (2) - Cache Hit

----- Ejemplo 2 -----

Lo malo:

(Tres elementos de una colección - tamaño de lote de 3)

En este caso, el elemento en el índice 0 era eliminado de la memoria caché porque tal vez la memoria caché estaba llena y el elemento se eliminó, o el elemento quedó obsoleto o inactivo.

  • collection.getItem (0) - No en caché también lo hacen por lotes de 3 (seleccionar * donde id en (,)???)
  • collection.getItem (1) - En caché Ya (reemplazado por lotes-fetch de todos modos)
  • collection.getItem (2) - En caché Ya (reemplazado por lotes-fetch de todos modos)

Así que la solución de compromiso aquí es que usted tendrá menos llamadas SQL debido al procesamiento por lotes, pero te faltará el caché más a menudo. Hay un boleto abierto para que el lote parezca en el caché de segundo nivel antes de que salga a la base de datos.

http://opensource.atlassian.com/projects/hibernate/browse/HHH-1775

Voto para arriba!

Cuestiones relacionadas