2013-07-22 7 views
5

„Im Gegensatz zu Identität, wird die nächste Nummer für den Spaltenwert aus dem Speicher anstatt von der Platte abgerufen werden - diese Sequenz deutlich schneller als Identität macht“ in diesen article definiert . Bedeutet es, dass ID von der Festplatte im Falle der Identität kommt, wenn ja dann welche Platte und wie. Mit der Sequenz kann ich im Log eine zusätzliche Select-Abfrage zu db sehen, während ich einen neuen Datensatz einfüge. Aber ich habe diese extra select-Abfrage im Protokoll nicht gefunden, wenn es sich um eine Identität handelt. Dann wie Sequenz schneller als Identität wird.Hibernate IDENTITY vs FOLGTE

Könnte jemand bitte einen wertvollen Einblick in diese Komplexität geben?

Antwort

0

Obwohl ich persönlich neu bei Hibernate bin, bedeutet die Verwendung von Identity grundsätzlich, dass Hibernate den nächsten möglichen ID-Wert aus Ihrer DB überprüft und einen Wert dafür behält.

Für die Sequenz weisen Sie Hibernate grundsätzlich an, den nächsten Wert basierend auf einer bestimmten Sequenz zu generieren. Also muss er die nächste ID berechnen, indem er den nächstmöglichen ID-Wert betrachtet. Daher wird die zusätzliche Abfrage ausgelöst.

0

vielleicht wird dies Ihre Frage beantworten:

Anders als Identitätsspaltenwerte, die erzeugt werden, wenn Reihen eingefügt sind, kann eine Anwendung die nächste Sequenznummer erhalten, bevor die Zeile einzufügen, indem Sie die NEXT VALUE fordern Funktion. Die Nummer wird zugewiesen, wenn NEXT VALUE FOR aufgerufen wird, auch wenn die Nummer niemals in eine Tabelle eingefügt wird. Die Funktion NEXT VALUE FOR kann als Standardwert für eine Spalte in einer Tabellendefinition verwenden. Verwenden Sie sp_sequence_get_range, um einen Bereich von mehreren Sequenznummern bei einmal zu erhalten.

Sie das Detail finden here

Identität benötigt nicht die zusätzliche Auswahlabfrage, weil Identität eine Tabelle abhängig ist und Sequenz von Tabelle unabhängig ist, sondern weil dies können wir Sequenz sogar erhalten, bevor eine Zeile zu schaffen (Wenn Sie session.save (T entity) ausführen, wird die Sequenz generiert, noch bevor Sie die Transaktion festgeschrieben haben.

Sequenz: Sie erstellen oder aktualisieren Entities -> jedes Mal, wenn Sie Entity speichern -> Hibernate get nächsten Sequenzwert -> Ihr Programm den Wert nach Abschluss aller Prozess ohne Ausnahme oder Rollback -> Sie verpflichten alle Transaktion -> Ruhezustand füge alle vollständigen Entitäten ein

identity: Wenn commit transaction, füge unvollständige Entity ein (muss aus der Identity-Spalte abgerufen werden). so ist die INSERT Befehl der Sequenz definitiv langsamer, aber die Vorteile sind, wenn Sie die Einfügung der Zählung nicht erhöhen.

+0

Danke. In der Tat bin ich auch durch die Links gegangen. Wenn die Identität diese extra Select-Abfrage nicht benötigt, könnten Sie bitte klarstellen, wie die Sequenz schneller wird als die Identität. – cooper

+0

im Debug-Modus und verwenden Sie die Entität, die Sequenz für ihre ID haben, ich speichern (vor dem Commit) eine Entität und diese Entität bereits ID, noch bevor die Zeile in der Datenbank vorhanden war. – Angga

7

Strategie von Sequenz verwendet:

eine neue Zeile vor dem Einsetzen, fragen Sie die Datenbank für den Wert nächsten Sequenz, dann fügen Sie diese Zeile mit dem Sequenzwert als ID zurückgegeben.

Strategie von Identität verwendet:

eine Zeile einfügen, ohne einen Wert für die ID angeben. Fragen Sie die Datenbank nach dem Einfügen der Zeile nach der zuletzt generierten ID.

Die Anzahl der Abfragen ist also in beiden Fällen gleich. Aber, Hibernate verwendet standardmäßig eine Strategie, die für den Sequenzgenerator effizienter ist. In der Tat, wenn es nach dem nächsten Sequenzwert fragt, behält es die nächsten Werte für den nächsten Wert 50 (das ist der Standardwert, IIRC und es ist konfigurierbar) und verwendet diese 50 nächsten Werte für die nächsten 50 Einsätze. Erst nach 50 Einfügungen geht es zur Datenbank, um die 50 nächsten Werte zu erhalten. Dies reduziert die Anzahl der benötigten SQL-Abfragen für die automatische ID-Generierung erheblich.

Die Identitätsstrategie erlaubt keine solche Optimierung.

+0

Ich würde auch hinzufügen, dass SQL Server "reserviert" eine Reihe von Sequenznummern in seinem Cache (also ** Speicher **). Standardmäßig ist es 50 (das ist wahrscheinlich auch der Grund, warum NH-Entwickler diesen Wert für ihren Zweck gewählt haben). Wenn diese 50 Nummern verwendet wurden, muss SQL Server seine Systemtabellen aktualisieren, die die zuletzt verwendete Nummer in einer bestimmten Reihenfolge speichern, um den nächsten Batch von Nummern zu "reservieren" - dies ist eine Operation ** für die Festplatte. Identitäten werden ebenfalls zwischengespeichert, aber die Cachegröße ist 5-mal verkleinert (zählt 10 Zahlen), und daher berührt der "Sequenzgenerator" die Festplatte häufiger. – lowleveldesign

+0

@JB, danke .Ich denke, das ist, was ich suchte.Aber was ist die Bedeutung von - "fragen Sie die Datenbank nach der letzten generierten ID" im Falle der Identität, ist es wie auto-increment.Can ich sage, dass es eine Datenübertragung auch in umgekehrter Richtung, von db zur Anwendung (round trip), im Falle von Identity und nur von Anwendung zu db (one way) im Falle von Sequence (vorausgesetzt, wir haben keine allocationSize für die Sequenz definiert) . Wahrscheinlich bin ich verwirrt, bitte korrigieren. Ich glaube, ohne allocationSize wird jeder db-Treffer ein Select auslösen, um die Sequenz zu erhalten. – cooper

+0

Ich kenne den genauen Low-Level-Mechanismus nicht, der von jeder Datenbank verwendet wird. Aber mit denen, die ich verwendet habe, ist ein zusätzlicher Rundgang zur Datenbank erforderlich, um die letzte automatisch generierte ID zu erhalten. –

4

Der IDENTITY generator erfordert immer einen Datenbanktreffer zum Abrufen des Primärschlüsselwerts, ohne darauf zu warten, dass der Flush den aktuellen entity state transitions mit der Datenbank synchronisiert.

Der IDENTITY-Generator spielt also nicht gut mit Hibernate write-behind First-Level-Cache-Strategie, daher ist JDBC Batching für IDENTITY Generator deaktiviert.

Der Sequenzgenerator kann von der Datenbankwertvorbelegung profitieren, und Sie können sogar eine HI/LO optimization strategy verwenden. Die besten Generatoren sind die pooled and pooled-lo sequence generators. Thes-Generatoren kombinieren den Batch-freundlichen Sequenzgenerator mit einer clientseitigen Wertgenerierungsoptimierung, die mit anderen DB-Clients kompatibel ist, die Zeilen einfügen können, ohne etwas über unsere Generierungsstrategie zu wissen.

Wie auch immer, sollten Sie niemals den TABLE-Generator wählen, weil it performs really bad. Wenn Sie Portabilität benötigen, können Sie sie mit überschreibenden Konfigurationen beheben, wie in this article erläutert.

+0

Was ist mit TABLE-Generator mit allocationSize config? Ist es auch schlecht? –

+0

[Es ist das Schlimmste] (https: // vladmihalcea.com/2017/01/04/why-you-sollte-nie-verwenden-the-table-identifier-generator-mit-jpa-and-hibernate /). Sie fragen dies, weil Sie nicht lesen müssen [meine 150 Hibernate Tutorials] (https://vladmihalcea.com/tutorials/hibernate/), richtig? –

+0

Nein, habe ich noch nicht. Ich werde Aurora verwenden und es unterstützt keine Sequenz. also studiere ich die Tischfolge ... danke für deine Artikel. –