本文介绍了Hibernate QueryTranslatorImpl HQL AST解析性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 @NamedEntityGraph findAll 查询时遇到性能问题>

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

  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解析?

解决方案
为了考虑性能,HQL查询计划被缓存。您可以使用以下:


  • 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解析性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 08:07