问题描述
使用 @NamedEntityGraph
当我检查日志时,我看到以下语句:
2016- 10-26 09:46:25,681 DEBUG [http-nio-8080-exec-1] CriteriaQueryImpl:渲染条件查询 - >从Patient选择generatedAlias0作为generatedAlias0 order by generatedAlias0.id asc
2016-10-26 09:46:25,681 DEBUG [http-nio-8080-exec-1] CriteriaQueryImpl:渲染条件查询 - > 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 patient0_
2016-10-26 09:46:25,682 DEBUG [http-nio-8080-exec-1]加载程序:结果行:
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
DEBUG [http-nio-8080 -exec-1] QueryTranslatorImpl:parse() - HQL:从com.fluidda.broncholab.domain.Patient选择generatedAlias0作为generatedAlias0 order by generatedAlias0.id asc
2016-10-26 09:46:27,340 DEBUG [http -nio-8080-exec-1] QueryTranslatorImpl:--- HQL AST ---
\- [QUERY]节点:'query'
+ - [SELECT_FROM]节点:'SELECT_FROM'
| + - [FROM]节点:'from'
| | \- [RANGE]节点:'RANGE'
| | + - [DOT]节点:'。'
| | | + - [DOT]节点:'。'
| | | | + - [DOT]节点:'。'
| | | | | + - [DOT]节点:'。'
| | | | | | + - [IDENT]节点:'com'
| | | | | | \- [IDENT]节点:'fluidda'
| | | | | \- [IDENT]节点:'broncholab'
| | | | \- [IDENT]节点:'domain'
| | | \- [IDENT]节点:'Patient'
| | \- [别名]节点:'generatedAlias0'
| \- [SELECT]节点:'select'
| \- [IDENT]节点:'generatedAlias0'
\- [ORDER]节点:'order'
+ - [DOT]节点:'。'
| + - [IDENT]节点:'generatedAlias0'
| \- [IDENT]节点:'id'
\ [ASCENDING] Node:'asc'
2016-10-26 09:46:27,340 DEBUG [http-nio- 8080-exec-1] ErrorCounter:throwQueryException():没有错误
2016-10-26 09:46:27,340 DEBUG [http-nio-8080-exec-1] HqlSqlBaseWalker:select<< begin [level = 1,statement = select]
2016-10-26 09:46:27,341 DEBUG [http-nio-8080-exec-1] FromElement:FromClause {level = 1}:com.fluidda.broncholab .domain.Patient(generatedAlias0) - > patient0_
QueryTranslatorImpl
log语句:将近2秒?!
当查看源代码时,我没有看到任何特别的东西(hibernate-core- 4.3.11.Final)
pre $ private私人HqlParser parse(布尔过滤器)抛出TokenStreamException,RecognitionException {
//解析将查询字符串转换为HQL AST。
final HqlParser parser = HqlParser.getInstance(hql);
parser.setFilter(filter);
LOG.debugf(parse() - HQL:%s,hql);
parser.statement();
final AST hqlAst = parser.getAST();
NodeTraverser walker = new NodeTraverser(new JavaConstantConverter());
walker.traverseDepthFirst(hqlAst);
showHqlAst(hqlAst);
parser.getParseErrorHandler()。throwQueryException();
返回解析器;
}
这里有什么问题?这是一个非常基本的HQL,为什么需要这么长时间?
是否可以缓存这些HQL AST解析?
-
hibernate.query.plan_cache_max_size
= 2048 (默认值)
-
hibernate.query.plan_parameter_metadata_max_size
= 128(默认值)
尝试将 hibernate.query.plan_cache_max_size
值增加到适合您的数据访问模式的值。
在我的书中,,我解释了为什么您应该正确配置这两个值,否则解析HQL查询可能会成为性能瓶颈。
I'm facing performance issues executing standard spring-data-jpa findAll
queries using @NamedEntityGraph
When I examine the logs, I see the following statements:
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 << begin [level=1, statement=select]
2016-10-26 09:46:27,341 DEBUG [http-nio-8080-exec-1] FromElement: FromClause{level=1} : com.fluidda.broncholab.domain.Patient (generatedAlias0) -> patient0_
There is a big gap between 2 QueryTranslatorImpl
log statements: almost 2 seconds?!
When looking in the source code, I don't see anything special (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;
}
What is the problem here? It is a very basic HQL, why does it takes so long?
Is it possible to cache these HQL AST parsing?
The HQL query plans are cached, for performance considerations. You can control the query plan cache using the following two configuration properties:
hibernate.query.plan_cache_max_size
= 2048 (default value)hibernate.query.plan_parameter_metadata_max_size
= 128 (default value)
Try increasing the hibernate.query.plan_cache_max_size
value to a value that's appropriate for your data access patterns.
In my book, High-Performance Java Persistence, I explained why you should configure these two values properly because otherwise parsing the HQL queries might become a performance bottleneck.
这篇关于Hibernate QueryTranslatorImpl HQL AST解析性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!