Behandlung von IDs / Performance und Optimierung
Wird ein Object/Relation Mapper wie bspw. Hibernate verwendet, so muss jede gemanagte Entity, die bspw. in einer Tabelle persistiert wird, eine ID besitzen.Es muss also etwas geben, dass eine solche Entity eindeutig identifiziert.
In JPA dient die Annotation @Id dazu.
Die Attribute zur Identifizierung können nach folgenden Aspekten ausgewählt werden:
- Nutzung eines fachlichen Schlüssels
- Nutzung/Generierung eines technischen Schlüssels
Für Variante 2 müssen für neue Objekte neue IDs generiert werden.
JPA Generatoren
Unter JPA kommen hier Generatoren zum Einsatz:
@GeneratedValue
Es gibt 3 Generatoren, die über den Annotation-Parameter strategy ausgewählt wird:
- IDENTITY
- SEQUENCE
- TABLE
- AUTO
IDENTITY
Bei IDENTITY kommt eine Autoincrement-Spalte zum Einsatz, wenn die darunterliegende DB dies unterstützt.SEQUENCE
Bei SEQUENCE wird ein eigener DB-seitiger Generator verwendet, der sich um das Hochzählen des Wertes kümmert.TABLE
Bei TABLE wird eine Tabelle hibernate_sequences angelegt, die die Werte des Generators hält.AUTO
Bei AUTO entscheidet hibernate anhand des eingestellten db-Dialekts, welcher Generator am Besten zu verwenden ist.
JPA PERFORMANCE
Performance
Grundsätzlich bedeuten technische Schlüssel eine schlechtere Performance, da beim persist der EntityManager/HibernateSessionFactory die von der DB vergebene ID auslesen muss.
Wehe den Datenbanken, die diese wichtige Operation per API nicht speziell anbieten.
Gibt es vom Treiber keine spezielle Operation bzw. Möglichkeit dies effizient einzulesen,
dann sind schlechtere Insert-Operation vorprogrammiert wie auf anderen Datenbanken.
Die AUTO-strategy kann auf bestimmten Datenbanken Performance kaputtmachen.
So kommt bei der Oracle-Datenbank eine Sequenz zum Einsatz, aber mit leider einer vorkonfigurierten allocationSize von 1.
Dies kann bei AUTO-strategy nicht eingestellt werden und bedeutet somit,
dass die Insert-Performance sehr schlecht ist, da nach jedem Insert über den Treiber die nächste verfügbare ID von der Sequenz ausgelesen werden muss.
So wird im Standard bei manueller Anlage oder bei Nutzung von Datenbanktools auf der DB2 und Oracle Sequences angelegt, die die nächsten 20 IDs cachen, so dass nicht nach jeder Einfügeoperation das Sequenzobjekt hierzu befragt werden muss.
CREATE SEQUENCE XY
START WITH 1
INCREMENT BY 1
NO MAXVALUE
NO CYCLE
CACHE 20;
INSERT INTO ORDERS (ORDERNO, CUSTNO)
VALUES (NEXT VALUE FOR XY, 123456);
Performance @GeneratedValue
Ist besondere Performance gefragt, kann man die Annotation @GeneratedVaule rausnehmen, so dass der JPA-Provider nicht mehr in der Verantwortung ist, eine ID zu ermitteln und bei persist zu setzen.
Dann muss man selber für eine ID-Generierung sorgen, dies kann hinsichtlich schwacher Treiber, deutlich schneller sein.
UUID-Klasse
Im java.util-Package gibt es seit Java 1.5 eine UUID-Klasse mit der man UUIDs generieren kann.
Eventuell sichert man dies noch mit eindeutigen Informationen aus dem jeweiligen Kontext ab, so dass die UUID wirklich eindeutig ist und nie per Zufall doppelt vergeben werden kann.
Dies hätte den Vorteil, dass nach der persist()-Methode ein Nachschlagen des vergeben Wertes für den DB-Treiber wegfiele.
Eine gute weiterführende Lektüre zum Thema ID Behandlung bietet folgendes Buch
(Kapitel 4 Abschnitt Mapping the Primary Key):
Eine gute weiterführende Lektüre zum Thema ID Behandlung bietet folgendes Buch
(Kapitel 4 Abschnitt Mapping the Primary Key):
Keine Kommentare:
Kommentar veröffentlichen