2016-08-01 14 views
6

Я очень новичок в Hibernate. Здесь я хотел бы сравнить два варианта.Hibernate Performance issue

Первый вариант

Мои Hibernate классы POJO следующим образом.

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

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

    @ManyToMany(fetch = FetchType.EAGER) 
    @JoinTable(name = "stock_characteristics", joinColumns = {@JoinColumn(name = "stock_id")}, inverseJoinColumns = {@JoinColumn(name = "ct_id")}) 
    private List<Characteristic> characteristics = new ArrayList<>(); 

    //constructor, getters and setters 

} 

Characteristics { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ct_id", nullable = false) 
    private Long id; 

    @Column(name = "name", nullable = false, length = 32) 
    private String name; 

    //constructor, getters and setters 
} 

Каждый товар содержит список характеристик. Всякий раз, когда я получаю запас, список характерных записей будет ассоциироваться, и результат будет получен.

В моей столовой таблице содержится более 1 миллиона записей и каждого запаса, связанного с 10 характеристиками (так что Stock_characteristics содержит более 10 миллионов строк). Когда мы получаем весь результат, связь между запасом и характеристикой может замедляться.

Второй вариант.

Я переписываю свои классы pojo следующим образом.

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

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

    //constructor, getters and setters 

} 

характеристики - такие же, как и выше и

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; 
    } 

Для получения моего результирующего набора, я передаю только набор характеристик. Например, если пропускная характеристика как 2, то сначала я нахожу идентификаторы запасов, которые имеют обе характеристики. Затем я буду проецировать данные о запасе из класса акций. Вот мой пример кода для первого варианта.

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(); 
    } 

Здесь вы можете увидеть присоединиться запрос выполняется между фондовым и характеристикой, которая может замедлить вниз и

вот мой пример код для второго варианта

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(); 
    } 

В качестве точки программной вид, который является лучшим выбором? или какой из них я должен использовать для повышения производительности?

ответ

0

Я думаю, что вы должны отобразить в спящем режиме все отношения между сущностями. Это поможет, если вы хотите использовать hql и критерии, иначе вы не сможете выполнять соединение между объектами.

Для выполнения, отметьте все ваши отображения ленивой и прочитать:

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

Я часто использую сервер MS SQL и проверить план выполнения моего медленного запроса, чтобы убедиться, что мой запрос хорошо индексируются , С помощью mysql вы можете использовать "show index"