Hibernate QueryTranslatorImpl HQL AST解析性能

我正面临使用@NamedEntityGraph执行标准spring-data-jpa findAll查询的性能问题

当我检查日志时,我看到以下语句:

 2016-10-26 09:46:25,681 DEBUG [http-nio-8080-exec-1] CriteriaQueryImpl: Rendered criteria query -> select generatedAlias0 from Patient as generatedAlias0 order by generatedAlias0.id asc 2016-10-26 09:46:25,681 DEBUG [http-nio-8080-exec-1] CriteriaQueryImpl: Rendered criteria query -> select count(generatedAlias0) from Patient as generatedAlias0 2016-10-26 09:46:25,681 DEBUG [http-nio-8080-exec-1] SQL: select count(patient0_.id) as col_0_0_ from patient patient0_ 2016-10-26 09:46:25,682 DEBUG [http-nio-8080-exec-1] Loader: Result row: 2016-10-26 09:46:25,682 DEBUG [http-nio-8080-exec-1] ConcurrentStatisticsImpl: HHH000117: HQL: select count(generatedAlias0) from Patient as generatedAlias0, time: 0ms, rows: 1 2016-10-26 09:46:25,682 DEBUG [http-nio-8080-exec-1] QueryTranslatorImpl: parse() - HQL: select generatedAlias0 from com.fluidda.broncholab.domain.Patient as generatedAlias0 order by generatedAlias0.id asc 2016-10-26 09:46:27,340 DEBUG [http-nio-8080-exec-1] QueryTranslatorImpl: --- HQL AST --- \-[QUERY] Node: 'query' +-[SELECT_FROM] Node: 'SELECT_FROM' | +-[FROM] Node: 'from' | | \-[RANGE] Node: 'RANGE' | | +-[DOT] Node: '.' | | | +-[DOT] Node: '.' | | | | +-[DOT] Node: '.' | | | | | +-[DOT] Node: '.' | | | | | | +-[IDENT] Node: 'com' | | | | | | \-[IDENT] Node: 'fluidda' | | | | | \-[IDENT] Node: 'broncholab' | | | | \-[IDENT] Node: 'domain' | | | \-[IDENT] Node: 'Patient' | | \-[ALIAS] Node: 'generatedAlias0' | \-[SELECT] Node: 'select' | \-[IDENT] Node: 'generatedAlias0' \-[ORDER] Node: 'order' +-[DOT] Node: '.' | +-[IDENT] Node: 'generatedAlias0' | \-[IDENT] Node: 'id' \-[ASCENDING] Node: 'asc' 2016-10-26 09:46:27,340 DEBUG [http-nio-8080-exec-1] ErrorCounter: throwQueryException() : no errors 2016-10-26 09:46:27,340 DEBUG [http-nio-8080-exec-1] HqlSqlBaseWalker: select < patient0_ 

2个QueryTranslatorImpl日志语句之间有很大差距: 差不多2秒?!

在查看源代码时,我没有看到任何特殊内容(hibernate-core-4.3.11.Final)

 private HqlParser parse(boolean filter) throws TokenStreamException, RecognitionException { // Parse the query string into an HQL AST. final HqlParser parser = HqlParser.getInstance( hql ); parser.setFilter( filter ); LOG.debugf( "parse() - HQL: %s", hql ); parser.statement(); final AST hqlAst = parser.getAST(); final NodeTraverser walker = new NodeTraverser( new JavaConstantConverter() ); walker.traverseDepthFirst( hqlAst ); showHqlAst( hqlAst ); parser.getParseErrorHandler().throwQueryException(); return parser; } 

这里有什么问题? 这是一个非常基本的HQL,为什么需要这么长时间?

是否可以缓存这些HQL AST解析?

出于性能考虑,HQL查询计划已缓存。 您可以使用以下两个配置属性控制查询计划缓存:

  • hibernate.query.plan_cache_max_size = 2048(默认值)
  • hibernate.query.plan_parameter_metadata_max_size = 128(默认值)

尝试将hibernate.query.plan_cache_max_size值增加到适合您的数据访问模式的值。

在我的书“ 高性能Java持久性”中 ,我解释了为什么要正确配置这两个值,否则解析HQL查询可能会成为性能瓶颈。