Estrategias de fetch Sistemas de persistencia de objetos
Fetch
Forma de recuperar objetos de la BDD y meterlos en contexto de persistencia En memoria los objetos forman un grafo por sus asociaciones Recorrer el grafo (navegar las asociaciones) es la forma natural de los modelos Orientados a Objetos Pero ¿cuándo y cómo se cargan en memoria?
nov-08
Alberto M.F.A.
[email protected]
2
Estrategia de fetch
¿Cuándo se suben de la BDD?
Los objetos asociados con un objeto dado
Dos momentos:
nov-08
LAZY: se cargan en el momento que se necesiten EAGER: se cargan al cargar el objeto que las asocia
Alberto M.F.A.
[email protected]
3
Estrategias de fetch
¿Cómo se cargan? (los asociados)
Ya sea LAZY o EAGER, en el momento que se decide cargarlos ¿cómo?
Varios tipos:
nov-08
Batch prefetch Subselect Eager JOIN Eager Select
Ajustes Hibernate
Alberto M.F.A.
[email protected]
4
Lazy load con proxies
nov-08
Es un proxy No se ha hecho select a la BDD
Alberto M.F.A.
[email protected]
¡ No selects !
5
Lazy load de asociaciones
nov-08
Las asociaciones son proxies -ToOne: Se cargan al refenrenciarlos -ToMany: Al acceder a cualquier método de la colección
Alberto M.F.A.
[email protected]
6
Configuración lazy: posibilidades
En JPA por defecto:
LAZY: asociaciones –ToMany EAGER: asociaciones –ToOne
Posibilidades:
Desactivar lazy para la clase
nov-08
Todas las cargas de esa clase serán siempre eager Ajuste demasiado grueso
-ToOne lazy -ToMany eager Alberto M.F.A.
[email protected]
7
Desactivar la carga lazy de una clase
Ya no carga proxy Al cargar el Item se cargan todos los usuarios relacionados por cualquier asociación
nov-08
Alberto M.F.A.
[email protected]
8
Carga eager
nov-08
Alberto M.F.A.
[email protected]
9
¿Cómo cargar las asociaciones?
Poco eficiente, el problema de las n+1 consultas
nov-08
Alberto M.F.A.
[email protected]
10
Prefetch en lotes
Ajuste: tamaño del lote Cuando se necesite hacer carga se suben en lotes de hasta el tamaño indicado Inconvenientes
Puede realizar cargas que después no se van a usar El tamaño del lote requiere ajuste
min(tamaño lote, los proxies User sin inicializar) nov-08
Alberto M.F.A.
[email protected]
11
Prefetch en lotes
nov-08
Alberto M.F.A.
[email protected]
12
Prefetch con subselects
Se realiza una segunda select que incluye a la primera como subselect No necesita ajustes Ideal si se va a recorrer toda la colección (o size(), contains())
nov-08
Alberto M.F.A.
[email protected]
13
Prefetch con subselects
nov-08
Alberto M.F.A.
[email protected]
14
Eager JOIN
Solo para estrategias EAGER Por defecto en colec. EAGER en JPA con Hibernate Atención a colecciones paralelas: ¡Producto cartesiano !
nov-08
Alberto M.F.A.
[email protected]
15
Eager JOIN
nov-08
Alberto M.F.A.
[email protected]
16
Eager con SELECT
Se lanza una segunda select en vez de JOIN para evitar producto cartesiano
nov-08
Alberto M.F.A.
[email protected]
17
Guía de optimización
Activar el log SQL en persistence.xml
Dejar todas las opciones por defecto. Ejecutar cada caso de uso observando el log para detectar cuales son los que generan un tráfico anómalo.
nov-08
Alberto M.F.A.
[email protected]
18
Guía de optimización (2)
Si hay mucho tráfico:
Ajustes en las queries.
nov-08
Si el tráfico se genera en algunos casos de uso concretos se puede mejorar el rendimiento dinámico solo para ellos. Suele ser la mejor estrategia. Emplear left join fetch o join fetch en las queries que generan más tráfico
Alberto M.F.A.
[email protected]
19
Guía de optimización (3)
Si sigue habiendo mucho tráfico:
Ajustes en los ficheros de mapeo
nov-08
Si son muchos los casos de uso afectados ajustar ficheros de mapeo (no es habitual). Para -to-one ponerFetchType.LAZY y batchsize=”” Colecciones de pocos elementos lazy=”false” y fetch=”subselect”
Alberto M.F.A.
[email protected]
20
Guía de optimización (4)
Ajustes en los ficheros de mapeo
nov-08
En caso necesario (muy raro y en general desaconsejado) se puede poner fetch=”join” en colecciones xxxx–to-many. Ojo colecciones paralelas. Atención a los caminos fetch=”join” que se forman al mapear varias asociaciones así. Se pueden cargar grafos muy profundos lo que supone subir muchos objetos a memoria. Se puede usar la propiedad max_fetch_depth para establecer el camino máximo. Alberto M.F.A.
[email protected]
21