Hibernate性能问题

时间:2016-08-01 05:07:49

标签: hibernate hibernate-mapping hibernate-criteria

我对Hibernate很新。 在这里,我想比较两个选项。

第一个选项

我的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
}

每只股票都包含一系列特征。每当我获取股票时,特征条目列表将关联并且结果正在获得。

我的库存表包含超过100万条记录,每条库存与10个特征相关联(因此stock_characteristics包含超过1000万行)。当我们获取整个结果时,库存和特征之间的关联可能会变慢。

第二个选项。

我按如下方式重写了我的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,那么首先我找到具有两个特征的股票ID。然后我将从Stock类投射股票详细信息。 这是第一个选项的示例代码。

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

在这里,您可以看到在Stock和Characteristics之间执行连接查询,这可能会减慢速度和

这是我的第二个选项的示例代码

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

作为一个程序观点,哪个是最佳选择?或者我应该使用哪一个以获得更好的表现?

1 个答案:

答案 0 :(得分:0)

我认为你应该在hibernate中映射实体之间的所有关系。如果您想使用hql和条件,它将有所帮助,否则您将无法在实体之间进行连接。

为了提高性能,请将所有映射标记为LAZY并阅读:

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

我经常使用MS SQL服务器并检查慢查询的执行计划,以确保我的查询编入索引。 使用mysql,您可以使用“show index”