Sospendi la strategia di recupero - quando utilizzare & # 8220; unisciti a & # 8221; e quando usare & # 8220; seleziona & # 8221 ;?

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

  •  03-07-2019
  •  | 
  •  

Domanda

La maggior parte delle associazioni di Hibernate supporta " fetch " Parametro:

fetch="join|select"

con " seleziona " essendo il valore predefinito.

Come decidere quale utilizzare per quale associazione?

Ho provato a cambiare tutto da " seleziona " per " unisciti " a livello di applicazione - il numero di query generate è diminuito probabilmente di 10 volte, ma le prestazioni sono rimaste esattamente le stesse (anche peggiorando leggermente).

Grazie.

È stato utile?

Soluzione

L'unione dovrebbe risolvere il problema n + 1. Se hai 10 genitori, ognuno con 10 figli, il join richiederà una query e selezionare ne richiederà 11 (uno per i genitori e uno per i figli di ciascun genitore). Questo potrebbe non essere un grosso problema se il database si trova sullo stesso server dell'applicazione o se la rete è molto veloce, ma se c'è latenza in ogni chiamata del database, può sommarsi. Il metodo join è un po 'meno efficiente nella query iniziale perché stai duplicando le colonne principali in ogni riga, ma fai solo un giro di andata e ritorno nel database.

Generalmente, se so che avrò bisogno dei figli di tutti i genitori, vado con unirsi. Se avrò solo bisogno dei figli di pochi genitori, userò select.

Altri suggerimenti

Seleziona recupererà gli elementi figlio emettendo una nuova query nel database per essi. Unisci recupererà gli elementi figlio unendoli alla query del genitore. Ecco perché stai riscontrando prestazioni simili, anche con un calo del numero di query.

Seleziona:

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

registrazione:

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

Su quando usare l'uno sull'altro ... Non del tutto sicuro. Probabilmente dipende dal sistema di database. Se uno fosse sempre migliore dell'altro, dubito che si preoccuperebbero di darti l'opzione! Se vedi prestazioni simili per ognuna, non me ne preoccuperei.

Se il genitore ha molti figli e quei figli a loro volta ne hanno molti altri, in questo caso il 'join' iniziale potrebbe soffocare la rete. Il mio suggerimento è di usare 'select' in questo caso per dividere le selezioni.

recupero = " unirsi " Se esegui il recupero = " join " recupererà tutte le informazioni in una singola istruzione select.

recupero = " seleziona " se desideri eseguire il paas della seconda istruzione select per recuperare la raccolta associata rispetto a quel caso utilizzerai fetch = " select " ;.

fonte: Hibernate Fetching Strategies

JOIN è preferito, in genere, per motivi di prestazioni.

L'unico motivo per usare SELEZIONA è se stai paginando i risultati (impostando un offset e un limite) che hanno una relazione molti-a-molti. Se usi JOIN, l'entità radice apparirà più volte se contiene molti bambini molti-a-molti e quelli "copie" contare contro il limite (anche se Hibernate li crolla dopo il fatto utilizzando DISTINCT_ROOT_ENTITY).

Le persone parlano sempre di hit delle prestazioni usando fetch = JOIN . Ma, secondo me, è importante per noi capire il numero di record genitore / figlio che stiamo recuperando:

Se vuoi recuperare solo un singolo record genitore e aspettandoti che non abbia molti figli, ti suggerirei di usare fetch = SELECT .

Se desideri recuperare tutti i record dei genitori, inclusi i relativi figli, sarebbe meglio scegliere fetch=JOIN

Solo per aggiungere una nota che, se i record recuperano pigramente i bambini ( pigro = vero ), allora non avrebbe alcun senso usare fetch = JOIN da tutte le registrazioni dei genitori e dei figli vengono caricate in una sola ripresa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top