2017-03-15 3 views
0

Ich habe folgende Tabellen in DB:Abfrage auf DB schnell ist, aber durch JPARepository holt langsam

Person, Parent, GrandParent Parent - Person ist OneToMany Beziehung (Person hat parentId) GrandParent - Parent ist ManyToMany Beziehung (grandparent_parent Tabelle)

Ich erstellt in PersonRepository, die JPARepository erweitert:

@Query("SELECT person.uuid FROM Person person JOIN person.parent parent JOIN parent.grandparents grandparent WHERE grandparent.uuid = ?1") 
Set<String> findByGrandParentId(final String parentId); 

Zum Abrufen aller IDs von Person, die unter GrandParent sind. Diese SQL erstellt:

SELECT 
    person0_.uuid as col_0_0_ 
FROM 
    person person0_ 
INNER JOIN 
    parent parent1_ 
     on person0_.parentid=parent1_.uuid 
INNER JOIN 
    grandparent_parent grandaparent_parent2_ 
     on parent1_.uuid=grandaparent_parent2_.parentid 
INNER JOIN 
    grandparent parent3_ 
     on grandaparent_parent2_.grandparentid=parent3_.uuid 
WHERE 
    parent3_.uuid='13906f55-441c-45bd-bef6-8beefa4119c4' 

ich angemeldet, wie viel Zeit Repository Bedürfnisse Daten holen, und es dauerte (Durchschnitt) ~ 400ms~ 400 Datensätze zu holen. Dann führe ich die gleiche SQL-Abfrage auf DB und jedes Mal dauerte Abfrage nicht mehr als 50ms.

Ich weiß, dass diese generierte Abfrage nicht optimiert ist, weil wir nur zwei Tabellen beitreten können GRANDPARENT_PARENT und PERSON, aber das ist hier nicht das Problem, da eine solche Abfrage auch unter 50ms ausgeführt wird.

Warum habe ich solche Unterschiede zwischen dem Abrufen von Repository und Abrufen in db? Ist es möglich, das zu beheben?

Antwort

2

Vielfältige Möglichkeiten:

1. Die erzeugte Abfrage

Die erzeugte Abfrage sieht für mich ziemlich gut. Es entspricht genau der Abfrage in Ihrer @Query Annotation.

2. SQL Ergebnis zu Java Object Umwandlung

Ich weiß nicht, wie groß Ihre Tabellen sind, aber: SQL Ergebnisse Konvertierung in Java Objects dauert einige Zeit. Bei kleinen Tabellen könnte dies die Abfragezeit um 0-5% erhöhen.

3. Lazy Loading

Sie nicht den Code für Ihre Entitäten zeigten. Wenn Sie @OneToMany oder @ManyToMany Relationen haben, verwendet JPA standardmäßig Lazy Loading. Dies kann wirklich alles um Größenordnungen verlangsamen.

4. Latency

Wenn Sie die SQL-Abfrage auf demselben Rechner ausführen, wo die SQL-DB, sondern Ihre Java-Anwendung kommuniziert über das Netzwerk mit der SQL-DB, es in vielen langsamen Abfragen führen kann, zu .

(5. Falsche Art von DB. Scheint so, als ob Sie ein Objektdiagramm erstellen.Vielleicht einen Blick auf Neo4j ;-))

+0

1. Wie gesagt, ich kann es zu einem Join ändern, aber Abfrage ist gut, wie Sie beschrieben. – ByeBye

+0

2,3. Wie Sie sehen, ich hole nur IDs, keine LazyLoading überall – ByeBye

+0

4. Nö, ich remote es von externen Maschine – ByeBye

Verwandte Themen