2013-07-22 20 views
5

"A differenza di identità, il numero successivo per il valore della colonna verrà recuperato dalla memoria piuttosto che dal disco - questo rende molto più veloce di identità di sequenza" definito in questo article. Significa che l'ID viene dal disco in caso di identità, se sì allora quale disco e come. Usando la sequenza, posso vedere nel registro, una query di selezione extra per db mentre si inserisce un nuovo record.Ma non ho trovato quella query di selezione extra nel registro in caso di identità. Quindi in che modo la sequenza diventa più veloce dell'identità.Hibernate IDENTITÀ vs SEQUENZA

Qualcuno potrebbe fornire preziose informazioni su questa complessità.

risposta

0

Anche se personalmente sono nuovo di Hibernate, da quello che posso ricordare, l'uso di Identity significa fondamentalmente che Hibernate controllerà quale sarà il prossimo valore id possibile dal DB e manterrà un valore per esso.

Per la sequenza, in pratica comunicate a Hibernate di generare il valore successivo in base a una particolare sequenza fornita dall'utente. Quindi deve effettivamente calcolare il prossimo id guardando il possibile valore id successivo. Quindi, la query aggiuntiva viene attivata.

0

forse questo sarà rispondere alla tua domanda:

A differenza di valori di colonna di identità, che vengono generati quando le righe sono inseriti, un'applicazione può ottenere il numero di sequenza successiva prima di inserire la fila chiamando il NEXT VALUE FOR funzione. Il numero della sequenza viene assegnato quando viene chiamato NEXT VALUE FOR anche se il numero non viene mai inserito in una tabella. La funzione NEXT VALUE FOR può essere utilizzata come valore predefinito per una colonna in una definizione di tabella. Utilizzare sp_sequence_get_range per ottenere una gamma di numeri di sequenza multipli a una volta.

è possibile trovare il dettaglio here

identità non ha bisogno di quel qualcosa in più query di selezione perché l'identità è una tabella dipendente e Sequence è indipendente dalla tabella, ma proprio per questo siamo in grado di ottenere sequenza anche prima di creare una fila (quando si esegue session.save (T entity), la sequenza viene generata anche prima di eseguire il commit della transazione).

sequenza: di creare o aggiornare le entità -> ogni volta che si salva entità -> ibernazione ottenere successivo valore di sequenza -> il programma restituisce il valore dopo tutto il processo completo senza eccezione o rollback -> si impegnano tutte le transazioni -> Hibernate inserisci tutta l'entità completa

identità: quando si esegue il commit della transazione, inserire un'entità incompleta (deve ottenerla dalla colonna Identity). quindi il comando INSERT di sequenza è decisamente più lento, ma i vantaggi è che se si annulla l'inserimento il conteggio non aumenta.

+0

Grazie. In effetti anch'io sono passato attraverso i link. Se l'identità non ha bisogno di questa query di selezione extra, puoi per favore chiarire come la sequenza diventa più veloce dell'identità. – cooper

+0

in modalità di debug e usa entità che ha una sequenza per il suo id, io salvo (prima del commit) un'entità e quell'entità ha già l'id anche prima che la riga esistesse nel database. – Angga

7

strategia utilizzata da sequenza:

Prima di inserire una nuova riga, chiedere al database per il successivo valore di sequenza, quindi inserire questa riga con il valore restituito come sequenza di ID.

strategia utilizzata da identità:

inserisce una riga senza specificare un valore per l'ID. Dopo aver inserito la riga, chiedere al database l'ultimo ID generato.

Il numero di query è quindi lo stesso in entrambi i casi. Ma, Hibernate utilizza per impostazione predefinita una strategia più efficiente per il generatore di sequenze. Infatti, quando richiede il successivo valore di sequenza, mantiene i 50 valori successivi (che sono predefiniti, IIRC e configurabili) nella memoria e utilizza questi 50 valori successivi per i successivi 50 inserti. Solo dopo 50 inserti, va al database per ottenere i 50 valori successivi. Ciò riduce enormemente il numero di query SQL necessarie necessarie per la generazione automatica dell'ID.

La strategia di identità non consente tale ottimizzazione.

+0

Vorrei anche aggiungere che SQL Server "riserva" un lotto di numeri di sequenza nella sua cache (quindi ** memoria **). Di default è 50 (probabilmente è anche il motivo per cui gli sviluppatori di NH hanno scelto questo valore per il loro scopo). Quando questi 50 numeri sono stati utilizzati, SQL Server deve aggiornare le sue tabelle di sistema che memorizzano l'ultimo numero utilizzato in una determinata sequenza, al fine di "riservare" il prossimo numero di numeri: si tratta di un'operazione ** disco **. Le identità sono anche memorizzate nella cache, ma la dimensione della cache è 5x ridotta (conta 10 numeri) e quindi il "generatore di sequenza" tocca il disco più frequentemente. – lowleveldesign

+0

@JB, grazie. Penso che questo è quello che stavo cercando.Ma qual è il significato di - "chiedere al database l'ultimo ID generato" in caso di identità, è come auto-incremento. Posso dire che c'è un trasferimento di dati anche nella direzione opposta, da db a application (round trip), in caso di Identity ed è solo dall'applicazione a db (one way) in caso di Sequence (supponendo che non abbiamo allocazione definita per sequenza) .Probabilmente sono confuso, per favore rettifica. Credo, senza allocazioneDimensioni ogni colpo db attiverà un Select per ottenere la sequenza. – cooper

+0

Non conosco il meccanismo di basso livello esatto utilizzato da ogni database. Ma con quelli che ho usato, è necessario un ulteriore roundtrip al database per ottenere l'ultimo ID generato automaticamente. –

4

Il IDENTITY generator richiederà sempre un riscontro di database per il recupero del valore della chiave primaria senza attendere che lo svuotamento sincronizzi l'attuale entity state transitions con il database.

Quindi il generatore IDENTITY non funziona bene con la strategia di cache di primo livello Hibernate write-behind, pertanto il batching JDBC è disabilitato per il generatore IDENTITY.

Il generatore di sequenze può trarre vantaggio dalla preallocazione del valore del database e si può anche utilizzare uno HI/LO optimization strategy.

A mio parere, i migliori generatori sono pooled and pooled-lo sequence generators. Questi generatori combinano il generatore di sequenze batch-friendly con un'ottimizzazione della generazione di valore lato client che è compatibile con altri client DB che possono inserire righe senza sapere nulla sulla nostra strategia di generazione.

In ogni caso, non si dovrebbe mai scegliere il generatore TABLE perché it performs really bad. Se hai bisogno di portabilità, puoi indirizzarlo con configurazioni di riserva, come spiegato in this article.

+0

E il generatore TABLE con allocationSize config? Anche questo è brutto? –

+0

[È il peggiore] (https: // vladmihalcea.com/2017/01/04/why-si-deve-mai-uso-the-table-identifier-generatore-con-APP-e-hibernate /). Lo stai chiedendo perché non devi leggere [i miei 150 tutorial Hibernate] (https://vladmihalcea.com/tutorials/hibernate/), giusto? –

+0

No, non l'ho ancora fatto. Userò aurora e non supporta la sequenza. quindi studio la sequenza del tavolo ... grazie per i tuoi articoli –