Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.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 Spring JPA Hibernate DeleteByColumnName的性能非常低效_Java_Mysql_Spring_Hibernate_Spring Data Jpa - Fatal编程技术网

Java Spring JPA Hibernate DeleteByColumnName的性能非常低效

Java Spring JPA Hibernate DeleteByColumnName的性能非常低效,java,mysql,spring,hibernate,spring-data-jpa,Java,Mysql,Spring,Hibernate,Spring Data Jpa,我试图使用Spring的crudepository与Hibernate一起使用deleteByColumnName方法,通过非主键列删除行。然而,实际执行的查询效率非常低,而且在实践中速度太慢 假设我有两个表Project和Employee,每个员工负责一些项目,这意味着Project表有一个字段Employee\u id。现在我想通过employee\u id删除一些项目。我写了这样的东西 public interface ProjectRepository扩展了crudepository{

我试图使用Spring的
crudepository
与Hibernate一起使用
deleteByColumnName
方法,通过非主键列删除行。然而,实际执行的查询效率非常低,而且在实践中速度太慢

假设我有两个表
Project
Employee
,每个员工负责一些项目,这意味着
Project
表有一个字段
Employee\u id
。现在我想通过
employee\u id
删除一些项目。我写了这样的东西

public interface ProjectRepository扩展了crudepository{
@交易的
作废deleteByEmployeeId(字符串employeeId);
}
我所期望的是Hibernate将为此方法执行以下查询

DELETE FROM Project
WHERE employee_id = ?
但是,Hibernate执行它的速度非常慢,就像

SELECT id FROM Project
WHERE employee_id = ?
Hibernate将上述结果存储在一个列表中,然后执行

DELETE FROM Project
WHERE id = ?
对于
N
次。。。(但它是成批执行的)

为了解决这个效率低下的问题,我必须通过直接编写SQL重写该方法,如

public interface ProjectRepository扩展了crudepository{
@查询(“从项目p中删除,其中p.employee_id=?1”)
@修改
@交易的
作废deleteByEmployeeId(字符串employeeId);
}
然后,行为将与我所期望的完全相同

当我在一个包含大约500k个条目的表中删除大约1k行时,性能会明显不同第一种方法需要45秒才能完成删除,而第二种方法只需要250毫秒

我使用Hibernate的原因是利用了它的ORM策略,它避免了直接使用SQL语言,从长远来看很容易维护。在这一点上,有没有人知道如何让Hibernate以我的第二种方法的方式执行删除而不直接编写SQL?在优化Hibernate性能方面,我是否缺少一些东西


提前谢谢

在这里,您可以找到一个很好的解释,为什么Hibernate在删除项目项时会有这种糟糕的性能

您是否启用了Hibernate批处理支持来删除savely Hibernate需要首先获取实体。如果执行
deleteById
,也会发生同样的情况。如果没有实体,它不知道它拥有的关系以及要删除的内容(可能是由于实体中的关系,它需要删除其他实体)。Spring数据有一个
deleteAllInBatch
,它在下面执行一个查询。因此,如果您想直接执行查询,唯一的方法就是自己指定查询。@MaxExplode谢谢您的评论。我确实启用了批处理,并且它确实在批处理中执行。但是,长时间运行查询“delete from table where id=?”是降低执行速度的瓶颈,而“delete from table where other_field=?”只执行一次。您好,欢迎使用stackoverflow。请直接发布一些信息,而不是共享链接。因为链接将来可能会断开/断开。谢谢,这篇文章真的很有用。因此,在这一点上,避免Hibernate默认操作,使用原始查询覆盖方法,并亲自处理关系是解决效率问题的唯一方法,对吗?是的,您应该编写自己的DELETE语句。