2009-03-05 16 views
43

asociaciones más Hibernate soportan "fetch" parámetro:Estrategia de búsqueda de Hibernate: cuándo usar "join" y cuándo usar "select"?

fetch="join|select" 

con "seleccionar" siendo el valor predeterminado.

Cómo decidir cuál usar los que la asociación?

He intentado cambiar todos de "seleccionar" a "unirse" a una amplia aplicación - número de consultas generadas disminuyó probablemente 10 veces, pero el rendimiento se mantuvo exactamente el mismo (incluso llegar a ser un poquito peor).

Gracias.

+0

Unir recuperará toda la información en una sola instrucción de selección mientras que en el otro caso si lo hace fetching = "select" Hibernate pasará la segunda instrucción select para recuperar la colección asociada a menos que deshabilite la recuperación lenta especificando lazy = "false "puedes encontrar más detalles aquí http://javawebtutorial.blogspot.in/2013/09/hibernate-fetching-strategies.html – user528050

Respuesta

38

se supone que se unen para resolver el problema n + 1. Si tiene 10 padres, cada uno con 10 hijos, join requerirá una consulta y seleccionará requerirá 11 (uno para los padres y otro 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á duplicando las columnas principales en cada fila, pero solo realiza un viaje de ida y vuelta a la base de datos.

En general, si sé que voy a necesitar los hijos de todos los padres, voy con unirse. Si solo voy a necesitar a los hijos de unos pocos padres, uso select.

+7

Hm, lo probé en la producción (tenemos servidor de db remoto con esclavos) y el comportamiento se mantuvo exactamente lo mismo - un poco peor que "seleccionar". Para ayudar con el problema n + 1, estamos usando "default_batch_fetch_size", por lo que ejecutará consultas seleccionadas en lotes, no una por una. – serg

9

Seleccionar buscará elementos secundarios mediante la emisión de una nueva consulta a la base de datos para ellos. Unir obtendrá objetos secundarios uniéndolos a la consulta principal. Es por eso que está viendo un rendimiento similar, incluso con un descenso en el número de consultas.

Seleccionar:

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

Ingreso:

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

En cuanto a cuándo utilizar uno sobre el otro ... No 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 ve un rendimiento similar para cada uno, no me preocuparía.

1

ir a buscar = "unir" Si ir a buscar = "unen" Será retrive toda la información en una sola instrucción de selección.

ir a buscar = "select" si quieres PAAS la segunda instrucción de selección para buscar la colección asociada que en este caso va a utilizar fetch = "seleccionar".

fuente: Hibernate Fetching Strategies

0

La gente siempre se habla de impacto en el rendimiento utilizando fetch = UNEN. Pero como reconozco, es importante que comprendamos la cantidad de registros padre/hijo que estamos obteniendo:

Si desea obtener solo un registro principal y esperar que no tenga muchos hijos, entonces sugeriría usted puede usar fetch = SELECCIONAR.

Si desea obtener todos los registros primarios incluidos sus hijos, entonces sería mejor ir a fetch = JOIN

Sólo para añadir una nota de que, si los registros están alcanzando perezosamente los niños (lazy = true), entonces no tendría sentido usar fetch = JOIN ya que todos los registros padre e hijo se cargan en una sola toma.

0

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

0

JOIN es preferido, generalmente, por motivos de rendimiento.

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

Cuestiones relacionadas