日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
概括潛在的Hibernate性能問題

學(xué)習(xí)Hibernate時(shí),經(jīng)常會遇到Hibernate性能問題,這里將介紹Hibernate性能問題的解決方法。

在使用Hibernate進(jìn)行分頁的過程中,如果你收到如下警告,那么這里就是一個(gè)潛在的Hibernate性能問題點(diǎn):

WARNING: firstResult/maxResults specified with collection fetch; applying in memory!

出現(xiàn)這個(gè)警告的直接后果是:無論你想要看第幾頁的數(shù)據(jù),從Hibernate打印出的SQL來看它總是查詢了所有滿足條件的結(jié)果。這是為什么呢?來看看這句警告所在的代碼,它位于org.hibernate.hql.ast.QueryTranslatorImpl中,部分摘錄如下:

 
 
 
  1. view plaincopy to clipboardprint?
  2. QueryNode query = ( QueryNode ) sqlAst;
  3. boolean hasLimit = queryParameters.getRowSelection() != null && 
    queryParameters.getRowSelection().definesLimits();
  4. boolean needsDistincting = ( query.getSelectClause().isDistinct() || hasLimit ) && 
    containsCollectionFetches();
  5. QueryParameters queryParametersToUse;
  6. if ( hasLimit && containsCollectionFetches() ) {
  7. log.warn( "firstResult/maxResults specified with collection fetch; applying in memory!" )
  8. RowSelection selection = new RowSelection();
  9. selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
  10. selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
  11. queryParametersqueryParametersToUse = queryParameters.createCopyUsing( selection );
  12. }
  13. else {
  14. queryParametersqueryParametersToUse = queryParameters;
  15. }
  16. List results = queryLoader.list( session, queryParametersToUse );
  17. QueryNode query = ( QueryNode ) sqlAst;
  18. boolean hasLimit = queryParameters.getRowSelection() != null && 
    queryParameters.getRowSelection().definesLimits();
  19. boolean needsDistincting = ( query.getSelectClause().isDistinct() || hasLimit ) && 
    containsCollectionFetches();
  20. QueryParameters queryParametersToUse;
  21. if ( hasLimit && containsCollectionFetches() ) {
  22. log.warn( "firstResult/maxResults specified with collection fetch; applying in memory!" );
  23. RowSelection selection = new RowSelection();
  24. selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
  25. selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
  26. queryParametersqueryParametersToUse = queryParameters.createCopyUsing( selection );
  27. }
  28. else {
  29. queryParametersqueryParametersToUse = queryParameters;
  30. }
  31. List results = queryLoader.list( session, queryParametersToUse ); 

關(guān)鍵在于if ( hasLimit && containsCollectionFetches() 這句判斷,如果滿足了這個(gè)條件,RowSelection將會被重新生成,原本分頁需要的firstRow和maxRows屬性將會丟失,后面的數(shù)據(jù)庫分頁自然也無法進(jìn)行。Hibernate這么做的原因從代碼上也很容易理解,如果查詢需要限制條數(shù)(limit/offset)并且需要fetch結(jié)合對象,則重新生成RowSelection,進(jìn)一步解釋,就是當(dāng)一個(gè)實(shí)體(A)和另一個(gè)實(shí)體(B)是One-To-Many關(guān)系的時(shí)候,一個(gè)需要fetch的典型查詢語句是“select distinct a from A a left join fetch a.b”,由于1個(gè)A可能對應(yīng)多個(gè)B,這個(gè)時(shí)候數(shù)據(jù)庫查詢的結(jié)果條數(shù)和需要生成的A對象的條數(shù)可能不一致,所以無法利用數(shù)據(jù)庫層的分頁來實(shí)現(xiàn),因?yàn)槟阏嬲敕猪摰氖茿而不是A left join B。出現(xiàn)這個(gè)警告就是提醒你這個(gè)查詢實(shí)際上是查詢了所有滿足條件的數(shù)據(jù),Hibernate是在內(nèi)存中對其進(jìn)行了假分頁的處理。

這樣,對于查詢結(jié)果比較多的情況無疑是一個(gè)Hibernate性能上的潛在威脅。碰到這樣的情況,將Many的查詢進(jìn)行分開也是一種解決辦法。


網(wǎng)頁名稱:概括潛在的Hibernate性能問題
地址分享:http://m.5511xx.com/article/dpeegdh.html