我试图使用Spring的CrudRepository与Hibernate一起使用deleteByColumnName方法,通过非主键列删除行。然而,实际执行的查询效率很低,实际执行速度太慢。
假设我有两个表Project和Employee,每个雇员负责一些项目,这意味着Project表有一个字段employee_id。现在我想删除employee_id的一些项目。我写了这样的东西
public interface ProjectRepository extends CrudRepository<Project, String> {
@Transactional
void deleteByEmployeeId(String 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 extends CrudRepository<Project, String> {
@Query("DELETE FROM Project p where p.employee_id = ?1")
@Modifying
@Transactional
void deleteByEmployeeId(String employeeId);
}然后,行为将与我所期望的完全一样。
当我在一个包含大约500 k条目的表中删除大约1k行时,性能基本上是不同的。第一种方法需要45秒才能完成删除,而第二种方法仅需250 45!
我之所以使用Hibernate,是因为它的ORM策略避免了SQL语言的直接使用,从长远来看,SQL语言很容易维护。在这一点上,是否有人知道如何让Hibernate以我的第二个方法的方式执行删除而不直接编写SQL?我是否缺少一些东西来优化Hibernate的性能?
提前感谢!
发布于 2019-12-02 15:04:43
在这里,您可以找到一个很好的解释,为什么Hibernate在删除项目项多对一和一对多关联映射的最佳实践时具有这种糟糕的性能
https://stackoverflow.com/questions/59080724
复制相似问题