如何优化hibernate查询?

时间:2016-11-08 04:05:58

标签: java spring postgresql hibernate query-performance

我是性能诊断和优化的新手。有一个基于Spring的Web应用程序,它使用由PostgreSQL支持的hibernate + EhCache + HikariCP。我正在运行SpringJUnit4ClassRunner测试 JProfiler是衡量和优化单个hibernate查询的主要工具。目标是发现并修复映射/获取反模式,导致查询执行时间过长 给定方案测试EhCache利用率和查询执行时间。据我所知,JDBC热门体育节目显示:

  1. 每个选择500 Address个实体的六个查询将占所有时间的5%。

    106 ms - 1 evt. 
    SELECT address0_.address_id  AS address_1_1_, 
           address0_.address     AS address2_1_, 
           address0_.address2    AS address3_1_, 
           address0_.city_id     AS city_id8_1_, 
           address0_.district    AS district4_1_, 
           address0_.last_update AS last_upd5_1_, 
           address0_.phone       AS phone6_1_, 
           address0_.postal_code AS postal_c7_1_ 
    FROM   dvdrental.PUBLIC.address address0_ limit ?
    

    30,161 micros - 6 evt. 
    SELECT     city0_.city_id        AS city_id1_3_0_, 
               city0_.city           AS city2_3_0_, 
               city0_.country_id     AS country_4_3_0_, 
               city0_.last_update    AS last_upd3_3_0_, 
               country1_.country_id  AS country_1_4_1_, 
               country1_.country     AS country2_4_1_, 
               country1_.last_update AS last_upd3_4_1_ 
    FROM       dvdrental.PUBLIC.city city0_ 
    inner join dvdrental.PUBLIC.country country1_ 
    ON         city0_.country_id=country1_.country_id 
    WHERE      city0_.city_id=?
    
  2. 正在检索City个实体2,910次(部分来自EhCache?)

  3. 3,657 ms - 2,910 evt。     SELECT city0_.city_id AS city_id1_3_0_,                city0_.city AS city2_3_0_,                city0_.country_id AS country_4_3_0_,                city0_.last_update AS last_upd3_3_0_,                country1_.country_id AS country_1_4_1_,                country1_.country AS country2_4_1_,                country1_.last_update AS last_upd3_4_1_     来自dvdrental.PUBLIC.city city0_     内联合dvdrental.PUBLIC.country country1_     ON city0_.country_id = country1_.country_id     在哪里city0_.city_id =?

    1. Store为什么不是国家?正在检索3,000次。 (部分来自EhCache?)

      5,660 ms - 3,000 evt。 SELECT store0_.store_id AS store_id1_12_13_,                 / *更多领域* /                 staff13_.username AS usernam10_11_12_ 来自dvdrental.PUBLIC.store store0_ 内联合dvdrental.PUBLIC.staff staff1_ ON store0_.manager_staff_id = staff1_.staff_id left outer join dvdrental.PUBLIC.address address2_ ON staff1_.address_id = address2_.address_id 左外连接dvdrental.PUBLIC.city city3_ ON address2_.city_id = city3_.city_id 左外连接dvdrental.PUBLIC.country country4_ ON city3_.country_id = country4_.country_id 左外连接dvdrental.PUBLIC.payment payment5_ ON staff1_.staff_id = payment5_.staff_id left outer join dvdrental.PUBLIC.customer customer6_ ON payment5_.customer_id = customer6_.customer_id left outer join dvdrental.PUBLIC.address address7_ ON customer6_.address_id = address7_.address_id left outer join dvdrental.PUBLIC.rental rental8_ 付款5_.rental_id = rental8_.rental_id 左外连接dvdrental.PUBLIC.customer customer9_ ON rental8_.customer_id = customer9_.customer_id 左外连接dvdrental.PUBLIC.inventory inventory10_ ON rental8_.inventory_id = inventory10_.inventory_id 左外连接dvdrental.PUBLIC.film film11_ ON inventory10_.film_id = film11_.film_id left outer join dvdrental.PUBLIC.LANGUAGE language12_ ON film11_.language_id = language12_.language_id 左外连接dvdrental.PUBLIC.staff staff13_ ON rental8_.staff_id = staff13_.staff_id 在哪里store0_.address_id =?

    2. 控制台:

      JProfiler> Protocol version 50
      JProfiler> Using JVMTI
      JProfiler> JVMTI version 1.1 detected.
      JProfiler> 64-bit library
      JProfiler> Instrumenting native methods.
      JProfiler> Can retransform classes.
      JProfiler> Can retransform any class.
      JProfiler> Native library initialized
      JProfiler> VM initialized
      JProfiler> Waiting for a connection from the JProfiler GUI ...
      JProfiler> Using dynamic instrumentation
      JProfiler> Time measurement: elapsed time
      JProfiler> CPU profiling enabled
      [timestamp] org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
      INFO: HHH000204: Processing PersistenceUnitInfo [
          name: default
          ...]
      [timestamp] org.hibernate.Version logVersion
      INFO: HHH000412: Hibernate Core {4.3.11.Final}
      [timestamp] org.hibernate.cfg.Environment <clinit>
      INFO: HHH000206: hibernate.properties not found
      [timestamp] org.hibernate.cfg.Environment buildBytecodeProvider
      INFO: HHH000021: Bytecode provider name : javassist
      [timestamp] org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
      INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
      [timestamp] org.hibernate.dialect.Dialect <init>
      INFO: HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
      [timestamp] org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
      INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
      [timestamp] org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
      INFO: HHH000397: Using ASTQueryTranslatorFactory
      [timestamp] org.hibernate.cfg.SettingsFactory buildSettings
      WARN: Unrecognized value for "hibernate.hbm2ddl.auto": none
      [timestamp] org.hibernate.cache.spi.UpdateTimestampsCache <init>
      INFO: HHH000250: Starting update timestamps cache at region: org.hibernate.cache.spi.UpdateTimestampsCache
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [org.hibernate.cache.spi.UpdateTimestampsCache]; using defaults.
      [timestamp] org.hibernate.cache.internal.StandardQueryCache <init>
      INFO: HHH000248: Starting query cache at region: org.hibernate.cache.internal.StandardQueryCache
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [org.hibernate.cache.internal.StandardQueryCache]; using defaults.
      [timestamp] org.hibernate.validator.internal.util.Version <clinit>
      INFO: HV000001: Hibernate Validator 5.2.2.Final
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [com.hibernate.query.performance.persistence.model.Address]; using defaults.
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [customer]; using defaults.
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [staff]; using defaults.
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [language]; using defaults.
      [timestamp] org.hibernate.dialect.Dialect <init>
      INFO: HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
      [timestamp] org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
      INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
      [timestamp] org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
      INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
      [timestamp] org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
      INFO: HHH000397: Using ASTQueryTranslatorFactory
      [timestamp] org.hibernate.cfg.SettingsFactory buildSettings
      WARN: Unrecognized value for "hibernate.hbm2ddl.auto": none
      [timestamp] org.hibernate.cache.spi.UpdateTimestampsCache <init>
      INFO: HHH000250: Starting update timestamps cache at region: org.hibernate.cache.spi.UpdateTimestampsCache
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [org.hibernate.cache.spi.UpdateTimestampsCache]; using defaults.
      [timestamp] org.hibernate.cache.internal.StandardQueryCache <init>
      INFO: HHH000248: Starting query cache at region: org.hibernate.cache.internal.StandardQueryCache
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [org.hibernate.cache.internal.StandardQueryCache]; using defaults.
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [com.hibernate.query.performance.persistence.model.Address]; using defaults.
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [customer]; using defaults.
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [staff]; using defaults.
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [language]; using defaults.
      [timestamp][main] ERROR - Starting QueryTimeWithEHCacheTest
      
      [timestamp] org.hibernate.cache.internal.StandardQueryCache <init>
      INFO: HHH000248: Starting query cache at region: address
      [timestamp] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory getCache
      WARN: HHH020003: Could not find a specific ehcache configuration for cache named [address]; using defaults.
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          30693123 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          0 nanoseconds spent preparing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          0 nanoseconds spent performing 0 L2C hits;
          0 nanoseconds spent performing 0 L2C misses;
          0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp][main] ERROR - Transaction #init took 4078 ms
      
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          26051941 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          215664108 nanoseconds spent preparing 987 JDBC statements;
          2115057343 nanoseconds spent executing 987 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          51375385 nanoseconds spent performing 501 L2C puts;
          0 nanoseconds spent performing 0 L2C hits;
          91260 nanoseconds spent performing 1 L2C misses;
          86065349 nanoseconds spent executing 1 flushes (flushing a total of 1093 entities and 1093 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      [timestamp][main] ERROR - Transaction #0 took 2469 ms
      
      INFO: Session Metrics {
          24727694 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          0 nanoseconds spent preparing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          0 nanoseconds spent performing 0 L2C hits;
          0 nanoseconds spent performing 0 L2C misses;
          0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          23262410 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          157571091 nanoseconds spent preparing 986 JDBC statements;
          1545907919 nanoseconds spent executing 986 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          13736681 nanoseconds spent performing 501 L2C hits;
          10272 nanoseconds spent performing 1 L2C misses;
          34459640 nanoseconds spent executing 1 flushes (flushing a total of 1093 entities and 1093 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          25324237 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          0 nanoseconds spent preparing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          0 nanoseconds spent performing 0 L2C hits;
          0 nanoseconds spent performing 0 L2C misses;
          0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          24041077 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          155411292 nanoseconds spent preparing 986 JDBC statements;
          1739510225 nanoseconds spent executing 986 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          5709031 nanoseconds spent performing 501 L2C hits;
          11852 nanoseconds spent performing 1 L2C misses;
          27861718 nanoseconds spent executing 1 flushes (flushing a total of 1093 entities and 1093 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp][main] ERROR - Transaction #1 took 2610 ms
      
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          23408584 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          0 nanoseconds spent preparing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          0 nanoseconds spent performing 0 L2C hits;
          0 nanoseconds spent performing 0 L2C misses;
          0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp][main] ERROR - Transaction #2 took 2288 ms
      
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          23451250 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          145723202 nanoseconds spent preparing 986 JDBC statements;
          1464820331 nanoseconds spent executing 986 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          5532445 nanoseconds spent performing 501 L2C hits;
          3160 nanoseconds spent performing 1 L2C misses;
          31112679 nanoseconds spent executing 1 flushes (flushing a total of 1093 entities and 1093 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          26841273 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          0 nanoseconds spent preparing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          0 nanoseconds spent performing 0 L2C hits;
          0 nanoseconds spent performing 0 L2C misses;
          0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          25004237 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          159031639 nanoseconds spent preparing 986 JDBC statements;
          1539390609 nanoseconds spent executing 986 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          5428922 nanoseconds spent performing 501 L2C hits;
          3161 nanoseconds spent performing 1 L2C misses;
          37890751 nanoseconds spent executing 1 flushes (flushing a total of 1093 entities and 1093 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp][main] ERROR - Transaction #3 took 2428 ms
      
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          24766806 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          0 nanoseconds spent preparing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          0 nanoseconds spent performing 0 L2C hits;
          0 nanoseconds spent performing 0 L2C misses;
          0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp] org.hibernate.engine.internal.StatisticalLoggingSessionEventListener end
      INFO: Session Metrics {
          26597126 nanoseconds spent acquiring 1 JDBC connections;
          0 nanoseconds spent releasing 0 JDBC connections;
          156316396 nanoseconds spent preparing 986 JDBC statements;
          1703458093 nanoseconds spent executing 986 JDBC statements;
          0 nanoseconds spent executing 0 JDBC batches;
          0 nanoseconds spent performing 0 L2C puts;
          4467764 nanoseconds spent performing 501 L2C hits;
          2765 nanoseconds spent performing 1 L2C misses;
          29417865 nanoseconds spent executing 1 flushes (flushing a total of 1093 entities and 1093 collections);
          0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
      }
      [timestamp][main] ERROR - Transaction #4 took 2543 ms
      
      JProfiler> Keeping VM alive until frontend disconnects.
      

      测试

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(classes = {ApplicationTestConfig.class, CachingConfig.class }, loader = AnnotationConfigContextLoader.class)
      @Transactional(transactionManager = "hibernateTransactionManager")
      public class QueryTimeWithEHCacheTest extends AbstractTransactionalJUnit4SpringContextTests {
      
          private static final org.apache.logging.log4j.Logger logger = LogManager.getRootLogger();
      
          @Autowired
          private SessionFactory sessionFactory;
      
          @Test
          public void testTransactionCaching(){
              logger.error("Starting QueryTimeWithEHCacheTest");
              long start = System.currentTimeMillis();
              Session session = sessionFactory.openSession();
              Query query = session.createQuery("from Address").setCacheable(true).setCacheRegion("address").setMaxResults(500);
      
              @SuppressWarnings("unchecked")
              List<Address> entities = query.list();
              session.flush();
              TestTransaction.flagForCommit();
              TestTransaction.end();
              session.clear();
              session.close();
              long end = System.currentTimeMillis();
              logger.error("Transaction #init took " + (end - start) + " ms");
      
              for (int i = 0; i < 5; i++) {
                  start = System.currentTimeMillis();
                  TestTransaction.start();
                  Session sessionNew =  sessionFactory.openSession();
                  Query anotherQuery = sessionNew.createQuery("from Address").setMaxResults(500);
                  anotherQuery.setCacheable(true).setCacheRegion("address");
                  @SuppressWarnings("unchecked")
                  List<Address> addressrFromCache = anotherQuery.list();
                  sessionNew.flush();
                  TestTransaction.flagForCommit();
                  TestTransaction.end();
                  sessionNew.clear();
                  sessionNew.close();
                  end = System.currentTimeMillis();
                  logger.error("Transaction #" + i  + " took " + (end - start) + " ms");
              }
          }
      }
      

      关于我的优化方法可以改进哪些方面?是否有任何明显的问题会降低查询执行速度?是否有改进查询的空间?

      enter image description here

0 个答案:

没有答案