Frage

Ich verwende Hibernate Implementierung von JPA und schlechter Leistung bin da mehrere SQL-Abfragen für jede Einheit ausgegeben werden, die abgerufen wird. Wenn ich eine verbundene JPA-Abfrage verwenden, erzeugt es nur eine SQL-Abfrage, aber keine Zeilen findet Beziehung null.

Beispiel, betrachten Sie dieses einfache Schema. Eine Person lebt an einer Adresse und wird von einem Unternehmen beschäftigt. Beide Adresse und Arbeitgeber sind optional und können somit null sein.

@Entity
public  class Person {
    public name;

    @ManyToOne
    @Column(nullable=true)
    public Address address

    @ManyToOne
    @Column(nullable=true)
    public Company employer
}

@Entity
public  class Address {
    address attributes ...
}

@Entity
public  class Company {
    company attributes ...
}

Nicht oben ist gezeigt, dass jede JPA-Entität eine Art von ID hat (Schlüssel):

@Id
public Integer id;

Das Problem, das ich zu sehen bin, ist, dass eine einzige PPV-Abfrage auf Person Ergebnisse in mehr SQL-Abfragen in der Datenbank. Zum Beispiel kann die folgende JPA-Abfrage:

select p from Person p where ...

Ergebnisse in der SQL-Abfrage:

select ... from Person where ...

und auch das folgende Paar von SQL-Abfragen für jede abgerufene Person:

select ... from Address a where a.id=xxx
select ... from Company c where c.id=yyy

Dies hat einen großen Einfluss auf die Leistung. Wenn das Abfrageergebnis 1000 Menschen ist, dann erzeugt es 1 + 1000 + 1000 = 2001 SQL-Abfragen.

So habe ich versucht, die JPA-Abfrage zu optimieren, indem sie zwingen zu verbinden:

select p from Person p join p.address a join p.employer e where ...

oder:

select p, a, e from Person p join p.address a join p.employer e where ...

Dies führt zu einer einzigen SQL-Abfrage mit einem Bündel von beitritt. Das Problem ist, wenn Adresse oder Arbeitgeber null ist, dann ist die Join-Abfrage wird es nicht finden.

Also ich bin mit links entweder der Join-Abfrage ohne Verwendung, die langsam ist, oder die schnelle Join-Abfrage, die Zeilen nicht abruft Beziehungen null. Ich muss hier etwas fehlen. Sicherlich gibt es eine Möglichkeit für eine schnelle und vollständige Abfrage.

War es hilfreich?

Lösung

Meine Vermutung ist, dass Sie eine LEFT JOIN bräuchten, d.h.

SELECT p FROM Person p LEFT JOIN p.address a LEFT JOIN p.employer e WHERE...

Siehe dieser Blog-Eintrag für ein Beispiel

Beachten Sie, dass ich habe nicht wirklich versucht, dies mit JPA, aber es funktioniert in HQL in Ordnung, welche die Grundlage für den JPA-Standard ist in vielerlei Hinsicht.

Der Grund, es nicht mit einfachen Arbeiten verbinden ist, dass der Standard ist eine innere Verknüpfung.

Andere Tipps

Versuchen Sie, eine Chargengröße (@BatchSize) auf die Adresse und Firmen Einheiten einstellen. Es lädt sie wird nicht in einem Join (ist das, was Sie wollen?), Aber es wird ein geladen wird ein Bündel von ihnen jedes Mal laden. Die Chargengröße sagt, wie viele es sollte laden, wenn es feststellt, dass es man braucht.

Wenn Sie eine Chargengröße von 1 (Standardeinstellung) haben, und die Last 10 Personen. Dann über sie iterieren, ihre Adresse und Firmen Artikel lesen, dann werden Sie den Ruhezustand eine Abfrage für die 10 Menschen, dann jedes Mal muss er die Adresse oder Firma für ein jene Leute, dann wird es eine Abfrage für diese Person der Adresse.

Wenn Sie eine Chargengröße von 7 auf der Entität Adresse dann festgelegt haben, wenn Sie die erste Adresse lesen, es wird sehen, dass es mehr als 7-Adressen, die derzeit proxied sind, und gehen und Ihnen 7 der Adressen erhalten.

Wenn Sie sowohl Adresse und Unternehmen mit einer Batchsize von 7 haben und Sie sind Iterieren durch 10 Personen, dann wird dies in 5 Abfragen führen, anstatt die 21 Jahre im Moment bekommen würden. Immer noch nicht die 1, die eine Wold Sie geben beizutreten. die Verknüpfung würde jedoch langsamer in den Fällen, in denen Sie nur die Person Objekte wollen und werden nicht die Adresse / Firma Einheiten eingebettet in ihnen berühren werden (sagen Sie wollen einfach nur eine Liste der Personen-IDs zu erhalten, oder zählen, wie viele männlich / weiblich)

Haben Sie einen Blick auf: http://hibernate.org/hib_docs/v3/reference/en/ html / performance.html

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top