2016-08-01 6 views
6

Ich bin sehr neu in Hibernate. Hier möchte ich zwei Optionen vergleichen.Hibernate Performance-Problem

Erste Option

Meine Hibernate pojo Klassen wie folgt.

Jedes Lager enthält eine Liste der Merkmale. Immer wenn ich den Bestand abhole, wird die Liste der charakteristischen Einträge verknüpft und das Ergebnis wird erhalten.

Meine Bestandstabelle enthält mehr als 1 Million Datensätze und jeder Bestand ist mit 10 Merkmalen verknüpft (so dass die Bestandsmerkmale mehr als 10 Millionen Zeilen enthalten). Wenn wir das gesamte Ergebnis abrufen, kann die Assoziation zwischen Aktie und Charakteristik langsam werden.

Zweite Option.

Ich überschreibe meine Pojo-Klassen wie folgt.

Stock { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "stock_id") 
    private Long stockId; 

    @Column(name = "stock_name") 
    private String stockName; 

    //constructor, getters and setters 

} 

Eigenschaften - wie oben und

StockCharacteristics { 
     @Id 
     @GeneratedValue(strategy = GenerationType.AUTO) 
     @Column(name = "id") 
     private Long id; 
     @Column(name = "stock_id", nullable = false) 
     private Long stockId; 
     @Column(name = "ct_id", nullable = false) 
     private Long ctId; 
    } 

Für meine Ergebnismenge bekommen, ich vorbei nur den Satz von Eigenschaften. Wenn zum Beispiel die Charakteristik 2 ist, dann finde ich zuerst die Aktien-IDs, die beide Charakteristiken haben. Dann projiziere ich die Bestandsdetails aus der Aktienklasse. Hier ist mein Beispielcode für die erste Option.

criteria.createAlias("stock.characteristics", "stockCharacteristics",  CriteriaSpecification.INNER_JOIN).add(Restrictions.in("stockCharacteristics.id", listOfSelectedCharacteristics)); 
    List<Object[]> projectedList = criteria.setProjection(Projections.projectionList().add(Projections.count("id")).add(Projections.groupProperty("id"))).list(); 
    List<Long> stockIdList = new ArrayList<>(); 
    for(Object[] entry: projectedList){ 
     if(((Long) entry[0]).intValue() == listOfSelectedCharacteristics.size()){ 
      stockIdList.add((Long)entry[1]); 
     } 
    } 

    if(!stockIdList.isEmpty()){ 
     Criteria criteriaWithCharacteristics = getDb(true).createCriteria(Stock.class, "stock").add(Restrictions.in("id", stockIdList)); 
     selectedStocks = criteriaWithCharacteristics.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list(); 
    } 

Hier können Sie eine Join-Abfrage sehen zwischen Vektor ausgeführt und Charakteristika, die die verlangsamen kann und

hier ist mein Beispielcode für die zweite Option

List<Object[]> stockIdList = //gets the stock id list from StockCharacteristics 
    if(!stockIdList.isEmpty()){ 
     Criteria criteriaWithCharacteristics = getDb(true).createCriteria(Stock.class, "stock").add(Restrictions.in("id", stockIdList)); 
     selectedStocks = criteriaWithCharacteristics.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list(); 
    } 

Als Programmpunkt anzeigen welche ist die beste option zu wählen? oder welche sollte ich für bessere Leistung verwenden?

Antwort

0

Ich denke, dass Sie im Winterschlaf alle Beziehungen zwischen Entitäten zuordnen sollten. Es wird hilfreich sein, wenn Sie hql und Kriterien verwenden möchten, ansonsten können Sie keine Verbindung zwischen Entitäten herstellen.

Für die Leistung, markieren Sie alle Ihre Mapping als LAZY und dies lesen:

https://zeroturnaround.com/rebellabs/how-to-use-jpa-correctly-to-avoid-complaints-of-a-slow-application/

Ich verwende oft MS SQL Server und prüfen Sie den Ausführungsplan meiner langsamen Abfrage, um sicherzustellen, dass meine Abfrage gut indiziert . Mit mysql können Sie "show index"

verwenden