Performance bei JPA Abfragen


Umgebung

  • Wildfly 10
  • Eclipselink

Wenn keine providerspezifischen Hilfskonstrukte verwendet werden, werden alle JPA-Abfragen in eine SQL-Anweisung überführt und an die Datenbank gesendet. Ausnahmen sind lediglich die Abfragen direkt über find(id) und interne Abhängigkeiten in den Objekten, die auf den Second-Level-Cache zugreifen. Somit wird der Cache in weiten Teilen nicht genutzt.

Dies hat zur Folge, dass bei Abfragen, die nicht über die find() Methode laufen, teure Datenbank Operationen ausgeführt werden müssen. Insbesondere bei großen Objekten mit vielen Unterobjekten, kann dies zu spürbaren Verzögerungen führen, da ggf. sehr viele Datenbank-Abfragen abgesetzt werden.

Nachvollzogen werden kann dies am besten, wenn SQL Logging eingeschaltet und eine Abfrage mit eine where-Bedingung mehrfach gestartet wird.

Eine Möglichkeit die Nutzung des Caches zu verbessern ist es, in den JPA-Abfragen lediglich die Id der gesuchten Objekte / des gesuchten Objektes abzufragen. Als Ergebnis erhält man z.B. eine Menge von Long-Werten (wenn das Objekt eine entsprechende Id hat). Die Objekte werden in einem zweiten Schritt über find() abgerufen und in das Ergebnis gehangen. Dies macht die Methoden für die Suche etwas länger, kann aber erhebliche Performance-Unterschiede bewirken, da nur noch eine sehr einfach SQL Abfrage statt vieler komplexer gesendet wird, wenn das Objekt im Cache ist. Dieses Vorgehen eignet sich für Objekte, die nicht nur einmal abgefragt werden (was wohl die meisten sind).

Wie immer ist dies nicht die Lösung aller Probleme. Der vorgestellte Weg kann aber einiges bewirken, ohne Features zu nutzen, die nicht von allen JPA-Providern unterstützt werden.

Du hast Fragen oder Anmerkungen? Kontakt: arndt@schoenb.de

,