如何告诉SpringJPA存储库中的my@query不要使用prepared语句(导致非常慢的查询)?

如何告诉SpringJPA存储库中的my@query不要使用prepared语句(导致非常慢的查询)?,spring,postgresql,jpa,prepared-statement,jpql,Spring,Postgresql,Jpa,Prepared Statement,Jpql,在我的Spring Repository类中,我在Postgresql 9.6服务器上运行以下查询(一种分析查询): @Query("SELECT d.id as departement_id, COUNT(m.id) as nbMateriel FROM Departement d LEFT JOIN d.sites s LEFT JOIN s.materiels m WHERE " + "(s.metier.id IN (:metier_id) OR :metier_id I

在我的Spring Repository类中,我在Postgresql 9.6服务器上运行以下查询(一种分析查询):

@Query("SELECT d.id as departement_id, COUNT(m.id) as nbMateriel FROM Departement d LEFT JOIN d.sites s LEFT JOIN s.materiels m WHERE "
        + "(s.metier.id IN (:metier_id) OR :metier_id IS NULL) AND (s.entite.id IN (:entite_id) OR :entite_id IS NULL) "
        + "AND (m.materielType.id IN (:materielType_id) OR :materielType_id IS NULL) AND "
        + "(d.id= :departement_id OR :departement_id IS NULL) "
        + "AND m.dateLivraison is not null  and (EXTRACT(YEAR FROM m.dateLivraison) < :date_id OR :date_id IS NULL) "
        + "AND ( m.estHISM =:estHISM OR :estHISM IS NULL OR m.estHISM IS NULL) "
        + "GROUP BY d.id")
List<Map<Long, Long>> countByDepartementWithFilter(@Param("metier_id") List<Long> metier_id,@Param("entite_id") List<Long> entite_id,@Param("materielType_id") List<Long> materielType_id,
        @Param("departement_id") Long departement_id, @Param("date_id") Integer date_id,
        @Param("estHISM") Boolean estHISM);
@Query(“选择d.id作为部门id,将(m.id)作为NBMaterials从部门d左加入d.sites左加入s.Materials m其中”
+(s.metier.id IN(:metier_id)或:metier_id为空)和(s.entite.id IN(:entite_id)或:entite_id为空)
+“和(:materialtype_id)中的m.materialtype.id或:materialtype_id为空)和”
+(d.id=:部门id或:部门id为空)
+“并且m.dateLivraison不为空并且(摘录(从m.dateLivraison开始的年份)<:date\u id或:date\u id为空)”
+“和(m.estHISM=:estHISM或:estHISM为空或m.estHISM为空)”
+“按d.id分组”)
列表CountByDepartmentWithFilter(@Param(“metier_id”)列表metier_id,@Param(“entite_id”)列表entite_id,@Param(“MaterialType_id”)列表MaterialType_id,
@Param(“department_id”)Long department_id、@Param(“date_id”)Integer date_id、,
@Param(“estHISM”)布尔estHISM);
问题是:使用不同的参数组合多次调用此查询,在5-6次调用后,执行时间从20毫秒变为10000毫秒

据我所知,这是由于使用了不适合分析查询的,其中有许多参数的值可能会发生很大变化。事实上,直接运行上述查询总是很快(20毫秒)

问题1:我如何告诉Spring JPA不要为这个特定查询使用准备好的语句


问题2:如果问题1不可能,我可以有什么解决方法?

从JPA/DB POV两个方面来看,通常有一些技巧可以提高查询性能:

1-使用@NamedQuery而不是@Query

2-对于报告查询,不要在事务内运行它

3-如果在查询运行之前不需要刷新持久性上下文,可以将刷新模式设置为提交

4-检查生成的查询,在SQL developer od TOAD上运行它,检查它的成本和运行策略,如果可以使用一些本机DB函数/provcedure对其进行增强,则还可以咨询DBA,因此使用本机查询而不是JPQL查询

5——如果数据返回量较大,请考虑将此查询设为DB视图或物化视图,并直接调用

6-使用查询提示激活某个索引。例如,请注意,在JPQL中,索引可能会被忽略

7-如果查询提示在JPQL上不起作用,则可以使用本机查询

8-在将SQL Developer上的查询与代码中的查询进行比较时,请确保比较正确,查询最初可能直接在DB上运行得非常快,但获取所有数据需要很长时间,并且您可能会将此初始短时间与应用程序数据获取时间进行比较

9-根据您的提供商使用获取大小提示


10-据我所知,如果您使用本机非参数化查询(因此使用手动占位符并手动替换值),您可能会逃过预处理语句但一般来说,由于SQL注入漏洞,这应该谨慎使用并尽可能避免,同时也不允许DB查询引擎和hibernate引擎预编译查询

nativeQuery=true
@AbdullahKhan谢谢。那么就没有机会保留JPQL语言了?Thx。但是,我确实在数据库日志中看到了生成的查询以及相关的执行时间。这就是为什么我很确定这个问题是由事先准备好的声明引起的,不应该使用。你的回答并没有告诉我如何通过准备好的语句并直接执行SQL欢迎兄弟。。我在我的回答中添加了一些要点,你可以把第10点看作是对任务1的回答,以及所有的其他点,就像我在写SQL查询时使用的任务2i使用的点10,映射到一个DTO=>没有更多的性能问题。