Estrategia de recuperación de Hibernate: cuándo usar & # 8220; join & # 8221; y cuándo usar & # 8220; seleccionar & # 8221 ;?

StackOverflow https://stackoverflow.com/questions/617145

  •  03-07-2019
  •  | 
  •  

Pregunta

La mayoría de las asociaciones de Hibernate admiten " buscar " parámetro:

fetch="join|select"

con " seleccione " siendo valor por defecto.

¿Cómo decidir cuál usar para qué asociación?

Intenté cambiar todo de " seleccionar " para " unirse a " amplio de aplicaciones: la cantidad de consultas generadas disminuyó probablemente 10 veces, pero el rendimiento se mantuvo exactamente igual (incluso empeorando un poco).

Gracias.

¿Fue útil?

Solución

Se supone que unirse para resolver el problema n + 1. Si tiene 10 padres, cada uno con 10 hijos, la inscripción requerirá una consulta y la selección requerirá 11 (uno para los padres y uno para los hijos de cada padre). Esto puede no ser un gran problema si la base de datos está en el mismo servidor que la aplicación o si la red es realmente rápida, pero si hay latencia en cada llamada a la base de datos, puede sumarse. El método de unión es un poco menos eficiente en la consulta inicial porque estás duplicando las columnas principales en cada fila, pero solo haces un viaje de ida y vuelta a la base de datos.

En general, si sé que voy a necesitar a los hijos de todos los padres, me uniré. Si solo voy a necesitar los hijos de algunos padres, utilizo select.

Otros consejos

Seleccionar buscará los elementos secundarios emitiendo una nueva consulta a la base de datos para ellos. Unirse buscará los elementos secundarios uniéndolos en la consulta de los padres. Por eso es que está viendo un rendimiento similar, incluso con una caída en el número de consultas.

Seleccionar:

SELECT * FROM parent WHERE id=(whatever)
SELECT * FROM child WHERE id=(parent.child.id)

Únete:

SELECT *
FROM parent
LEFT OUTER JOIN child ON parent.child.id=child.id
WHERE parent.id=(whatever)

En cuanto a cuándo usar uno sobre el otro ... No del todo seguro. Es probable que dependa del sistema de base de datos. ¡Si uno siempre fue mejor que el otro, dudo que se molesten en darle la opción! Si estás viendo un rendimiento similar para cada uno, no me preocuparía.

Si el padre tiene muchos hijos y esos hijos a su vez tienen muchos otros, entonces, en este caso, la "unión" inicial puede ahogar la red. Mi sugerencia es usar 'seleccionar' en este caso para dividir los seleccionados.

fetching = " unirse " Si realiza la búsqueda = " unirse " recuperará toda la información en una sola declaración de selección.

fetching = " seleccione " si desea paas la segunda declaración de selección para obtener la colección asociada, en ese caso utilizará fetch = " seleccione " ;.

fuente: Hibernate Fetching Strategies

JOIN se prefiere, normalmente, por motivos de rendimiento.

La única razón para usar SELECT es si estás paginando resultados (configurando un desplazamiento y un límite) que tienen una relación de muchos a muchos. Si usas JOIN, la entidad raíz aparecerá varias veces si contiene varios hijos de muchos a muchos y esas " copias " cuente en contra de su límite (incluso si Hibernate los colapsa después de usar DISTINCT_ROOT_ENTITY).

Siempre se habla de éxito en el rendimiento utilizando fetch = JOIN . Pero como creo, es importante para nosotros entender la cantidad de registros de padres / hijos que estamos obteniendo:

Si desea obtener solo el registro de Padres solteros y espera que no tenga muchos hijos, le sugiero que use fetch = SELECCIONAR .

Si desea recuperar todos los registros primarios, incluidos sus secundarios, sería mejor ir a buscar = IRIN

Solo para agregar una nota que, si los registros son perezosos en busca de niños ( lazy = true ), entonces no tendría ningún sentido usar fetch = JOIN ya que todos los registros primarios y secundarios se cargan en un solo disparo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top