【发布时间】:2015-05-26 14:59:16
【问题描述】:
我的 Java EE 应用程序适用于两个表应用程序的相当大的关系数据库。每行 350 万行。这两个表被命名为“用户”和“设备”——在“设备”表上使用 FK 一对多。 我需要为用户提取设备。查询很简单:
SELECT * FROM Device d WHERE d.user_id = 'some_id'
我使用的是 SQL Server 2012,这个查询需要不到 1 毫秒的时间来运行。但是当我使用 Criteria API 或 JPQL 或 Native JPA Query 时,它需要超过 1 秒!
如果我将 Collection 存储在用户的类中并懒惰地获取设备,则需要超过 200 毫秒。
我正在使用休眠。
也许缺少信息来回答我的问题,如果是这样,请说明我应该提供哪些信息。
那么,当使用 JPA 处理大型数据集(如我所提到的 350 万)时,性能如此低下的原因可能是什么?
抱歉英语不好。
更新。 代码,需要 200 毫秒
Collection<Device> userDevices = user.getDevices();
for (Device device : userDevices) {
if (device.getActive() && device.isToken())
sender.sendSms(user.getMobilePhone(), text); // costs 0, i am using a stub
}
还有用户类:
@Entity
public class User {
@Id
private String userId;
private String name;
//bla bla bla
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private Collection<Device> devices;
//bla bla bla
public Collection<Device> getDevices() {
return devices;
}
}
【问题讨论】:
-
你
index你的数据了吗? -
索引与否,JPA 处理 Java 对象,并且想象将 ResultSet 中的数百、数千甚至数百万行转换为 Java 对象集合不会有任何开销,这有点天真。如果您有具体问题,您需要发布一些代码和映射以及一些时间安排。
-
您的用户“some_id”有多少台设备?我们说的是 O(10) 还是 O(10000)? Hibernate 在您的测试用例中执行了哪些 SQL 查询?您确定您没有测量在代码中打开连接所用的时间吗?还是用于创建会话工厂的时间?发布您的测试用例的代码。
-
请尝试记录 Hibernate 的 SQL 查询。看看docs.jboss.org/hibernate/orm/4.3/topical/html/logging/…,当您知道 SQL Hibernate 实际发送到您的数据库的内容时,通常可以最好地解决性能问题。
-
我不是 SQLServer 专家,但如果
device.userId上存在索引并且数据库确实使用该索引,则代码没有理由花费那么长时间。我的猜测是非参数化查询使用了 Hibernate 使用的参数化查询不使用的缓存/索引。 Hibernate 不可能花费 200 毫秒。创建三个设备实例。所以要么是数据库是罪魁祸首,要么是sender.sendSms()是那个花了这么多时间的人。
标签: java sql-server performance hibernate jpa