Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA/Hibernate性能_Java_Sql Server_Performance_Hibernate_Jpa - Fatal编程技术网

Java JPA/Hibernate性能

Java JPA/Hibernate性能,java,sql-server,performance,hibernate,jpa,Java,Sql Server,Performance,Hibernate,Jpa,我的javaee应用程序使用两个表app的相当大的关系数据库。每行350万行。这两个表分别命名为“User”和“Device”——一对多,FK位于“Device”表上。 我需要为用户提取设备。查询非常简单: SELECT * FROM Device d WHERE d.user_id = 'some_id' 我正在使用SQL Server 2012,运行此查询需要不到1毫秒的时间。但当我使用CriteriaAPI、JPQL或本机JPA查询时,它需要超过1秒 如果我将一个集合存储在一个用户类中并

我的javaee应用程序使用两个表app的相当大的关系数据库。每行350万行。这两个表分别命名为“User”和“Device”——一对多,FK位于“Device”表上。 我需要为用户提取设备。查询非常简单:

SELECT * FROM Device d WHERE d.user_id = 'some_id'
我正在使用SQL Server 2012,运行此查询需要不到1毫秒的时间。但当我使用CriteriaAPI、JPQL或本机JPA查询时,它需要超过1秒

如果我将一个集合存储在一个用户类中并延迟获取设备,则需要超过200毫秒

我正在使用Hibernate

也许是因为缺少信息来回答我的问题,如果是的话,请说明我应该提供什么信息

那么,性能如此低的原因可能是什么?在使用JPA处理大型数据集(我提到的350万)时,主要的模式是什么

Sry为英语差而设

upd。 代码,需要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
}
Collection userDevices=user.getDevices();
用于(设备:用户设备){
if(device.getActive()&&device.isToken())
sender.sendSms(user.getMobilePhone(),text);//成本为0,我正在使用存根
}
和用户类:

@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;
    }
}
@实体
公共类用户{
@身份证
私有字符串用户标识;
私有字符串名称;
//呜呜呜呜
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,mappedBy=“user”)
私人收集设备;
//呜呜呜呜
公共收集设备(){
返回装置;
}
}

当您运行JPQL查询时,结果本身不一定是从数据库中获取的唯一内容(您不一定要查询单个查询)

如果您的
设备
类引用了一个
用户
(或多个),则在查询
设备
时也会加载
用户
。此外,实例化对象并在
EntityManager
中注册它们也会带来一些开销(尽管我怀疑这个开销没有那么大)

本质上,您不能期望JPQL查询的运行速度与SQL查询的运行速度一样快,因为尽管它们在语法上很相似,但它们却大不相同

如果您编写一个本机sql查询并通过Hibernate运行它,我希望它所花费的时间与直接运行sql查询所花费的时间差不多

当谈到延迟加载时,Hibernate需要重新访问数据库以检索延迟加载的实体,这当然需要一些时间。加载所属对象可以节省时间,但一旦尝试加载延迟获取关联,节省的时间就会花掉(尽管,从我所看到的情况来看,快速获取所花费的时间与延迟获取和延迟加载所花费的时间差不多,两者之间仅相隔几毫秒。)

如果要查看Hibernate根据JPQL查询生成的sql,请将
true
添加到Hibernate配置中,并将以下内容添加到log4j.properties中:

log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE

问题是Java用Unicode发送查询参数,SQLServer也必须将所有列转换为Unicode。将sendStringParametersAsUnicode=false参数设置为persistence.xml中的connection将有所帮助。 这段代码耗资200毫秒,现在只需2-5毫秒。 不幸的是,我花了两天时间来寻找原因,正如我所想,问题出在Hibernate中。
请参阅:

您是否对数据进行了
index
索引?是否索引,JPA处理Java对象,设想将结果集中的数百行、数千行甚至数百万行转换为Java对象集合不会产生任何开销,这有点幼稚。如果您有特定的问题,您需要发布一些代码、映射和一些计时。您的用户“some_id”有多少设备?我们说的是O(10)还是O(10000)?在您的测试用例中,Hibernate执行了哪些SQL查询?您确定没有在代码中测量打开连接所用的时间吗?或者创建会话工厂所用的时间?发布测试用例的代码。请尝试记录Hibernate的SQL查询。请看一看,当您知道SQL Hibernate实际向数据库发送的是什么时,性能问题通常会得到最好的解决。我不是SQLServer专家,但如果
设备上存在索引,则代码没有理由花费那么长时间。userId
,并且数据库确实使用此索引。我的猜测是,非参数化查询使用了Hibernate使用的参数化查询不使用的缓存/索引。Hibernate不可能花费200毫秒来创建设备的三个实例。所以要么是数据库造成的,要么是发送者造成的。sendSms()花费了太多时间。笑话是,获取用户设备的本机SQL查询需要超过1秒才能完成。而从SQLServer控制台执行相同的查询所需的时间不到1毫秒。也许,Hibernate会为每个查询重新打开连接,然后我会检查我的SQL驱动程序。使用jTDS驱动程序,微软的驱动程序有很多怪癖。这不是一个好的答案。回答他自己的问题是可以的,但答案应该提供解释,而不仅仅是指向其他地方的链接。