创建JPA本机查询很慢

时间:2014-05-22 04:26:41

标签: java performance java-ee jpa eclipselink

  • 数据库:MySQL 5.1
  • JPA实现:EclipseLink
  • 容器:Glassfish 4
  • Java:JDK 7u55

我使用本机查询从订单表中获取结果。每个订单都有一个日期,我只想按年份和日期选择。整个方法都有这个主体。

    Query query = entityManager.createNativeQuery("SELECT COUNT(PLACED_ORDER.ID) as POCET_OBJEDNAVEK FROM PLACED_ORDER WHERE ORDERDATE IS NOT NULL AND EXTRACT(YEAR FROM ORDERDATE) = ?1 AND extract(DAY FROM ORDERDATE) = ?2");
    query.setParameter(1, year);
    query.setParameter(2, day);

    return (Long) query.getSingleResult();

此查询 WORKS 正确,但执行速度很慢。慢,我的意思是每个方法调用一秒钟或更长时间。事务管理设置为必需。

命名查询在几毫秒内执行,从请求到响应进行测量。单独调用此方法非常慢。有什么可以做的吗?

编辑 - 对评论的反应:

当我从命令行或通过MySQL WorkBench查询数据库时,性能正常(在重负载下最多一毫秒或几个)。

我还应该注意项目中的 SECOND LEVEL CACHE 已禁用,我无能为力。

MySQL Explain看起来像这样(我没有简单的方法在EclipseLink上启用解释)。

enter image description here

用于确定数据类型和数据库约束的实体注释。

@Entity(name = "PLACED_ORDER")
public class Order implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne
@JoinColumn(name = "CUSTOMER_ID")
private Customer customer;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.REMOVE, CascadeType.PERSIST}, orphanRemoval = true)
@JoinColumn(name = "PLACED_ORDER_ID")
private List<OrderItem> items;
@Temporal(TemporalType.TIMESTAMP)
private Date orderDate;
@Enumerated(EnumType.STRING)
@NotNull
private OrderState orderState = OrderState.SEMIFINISHED;
@OneToOne
private Transportation transportation;
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, orphanRemoval = true)
private Address deliveryAddress;
@Enumerated(EnumType.STRING)
private TransportationType transportationType;

1 个答案:

答案 0 :(得分:0)

使用问题中指定的技术和禁用二级缓存,解决方案是将本机查询编写为 @NamedNativeQuery ,而不是每次调用方法时都创建它。这样,性能显着提高。