带Group By子句的JPQL在SQL Server 2019无响应MySQL正常问题咨询
1. 修正JPQL写法,消除不必要的关联查询
你当前的JPQL为了过滤jobId主动关联了AnalysisJob表,实际上可以直接通过RiskViolation的job.id属性直接过滤,无需显式关联AnalysisJob,减少关联表带来的性能开销:
@Query(value = "SELECT R.riskType, count(distinct V.bname) FROM RiskViolation V JOIN V.risk R WHERE V.job.id = ?1 GROUP BY R.riskType ") public List<Object[]> sodUserByRiskType(Long jobId);
修改后Hibernate生成的SQL会直接过滤risk_violation.job_id字段,不需要再关联analysis_job表,执行效率更高。
2. 修正实体类的加载策略,避免不必要的关联加载
当前你在RiskViolation的两个@ManyToOne关联上都使用了FetchType.EAGER,每次查询RiskViolation实体都会强制加载关联的AnalysisJob和RiskLog对象,即使是投影查询部分场景下也会触发额外的查询,建议修改为FetchType.LAZY,需要关联查询时再通过FETCH JOIN加载:
// 修改RiskViolation中的关联注解 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "job_id") private AnalysisJob job; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "risk_id") private RiskLog risk;
3. 检查Hibernate方言配置,避免参数类型不匹配
确认你的项目中配置了正确的SQL Server 2019方言,旧版本方言会导致参数绑定类型不匹配,触发SQL Server隐式类型转换,导致索引失效、查询挂起:
# Spring Boot配置示例 spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2019Dialect
同时可以在JDBC连接参数中添加sendStringParametersAsUnicode=false,避免字符串参数默认转为NVARCHAR触发隐式转换:
spring.datasource.url=jdbc:sqlserver://<host>:<port>;databaseName=<dbname>;sendStringParametersAsUnicode=false
4. 备选方案:直接使用原生SQL查询
如果修改JPQL后仍然存在问题,因为你转换后的原生SQL在SQL Server中执行正常,可以直接指定原生查询:
@Query(value = "select risklog2_.risk_type as col_0_0_, count(distinct riskviolat0_.bname) as col_1_0_ from risk_violation riskviolat0_ inner join risk_log risklog2_ on riskviolat0_.risk_id=risklog2_.id where riskviolat0_.job_id=?1 group by risklog2_.risk_type", nativeQuery = true) public List<Object[]> sodUserByRiskType(Long jobId);
内容的提问来源于stack exchange,提问作者Ram
相关产品推荐
相关产品推荐

