2017-02-08 2 views
1

Ich habe etwa 1,4 Millionen Datensätze, aber es dauert mehr als 3 Stunden, um sie einzufügen. Ich kann das Problem nicht finden.Wie kann die Einfüge-Abfragezeit mithilfe von Hiberate optimiert werden?

Ich lese und ändere von Identität zu Sequenz. Es hat sich nur ein wenig verbessert, aber es dauert immer noch ziemlich lange, bis das Einfügen abgeschlossen ist.

Ich verwende:

  • Hibernate 5
  • Spring 4
  • mssql 2014
  • Wildfly 10

application-hibernate.xml

<tx:advice id="txAdvice"> 
     <!-- the transactional semantics... --> 
     <tx:attributes> 
      <tx:method name="*_TransNew" propagation="REQUIRES_NEW" /> 
      <tx:method name="*_NoTrans" propagation="NEVER" /> 

      <tx:method name="create*" propagation="REQUIRED" /> 
      <tx:method name="update*" propagation="REQUIRED" /> 
      <tx:method name="delete*" propagation="REQUIRED" /> 
      <tx:method name="add*" propagation="REQUIRED" /> 

      <tx:method name="generate*" propagation="REQUIRED" /> 
      <tx:method name="get*" propagation="REQUIRED" /> 
      <tx:method name="is*" propagation="REQUIRED" /> 

      <!-- other methods use the default transaction settings (see below) --> 
      <tx:method name="*" read-only="true" /> 
     </tx:attributes> 
    </tx:advice> 


    <!-- ensure that the above transactional advice runs for any execution of 
     an operation defined by the following --> 
    <aop:config> 
     <aop:pointcut id="demoServiceOperations" 
      expression="execution(* com.test.*.*.*(..))" /> 
     <aop:advisor advice-ref="txAdvice" pointcut-ref="demoServiceOperations" /> 
    </aop:config> 

<bean id="sessionFactory" 
     class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.show_sql">true</prop> 
       <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2012Dialect</prop> 
       <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop> 
       <prop key="hibernate.cache.use_second_level_cache">true</prop> 
       <prop key="hibernate.cache.use_query_cache">true</prop> 
       <prop key="hibernate.jdbc.batch_size">50</prop> 
       <prop key="hibernate.order_inserts">true</prop> 
       <prop key="hibernate.order_updates">true</prop> 

       <prop key="hibernate.c3p0.min_size">5</prop> 
       <prop key="hibernate.c3p0.max_size">20</prop> 
       <prop key="hibernate.c3p0.timeout">1800</prop> 
       <prop key="hibernate.c3p0.max_statements">50</prop> 


      </props> 
     </property>   
    </bean> 

Umts.hbm.xml:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<!-- Generated Nov 22, 2016 11:36:21 AM by Hibernate Tools 5.2.0.Beta1 --> 
<hibernate-mapping> 
    <class name="com.test.domain.Umts" table="TBLDM_UMTS" schema="dbo" catalog="DEMO" optimistic-lock="version" dynamic-update="true"> 
     <id name="umtsId" type="java.lang.Integer"> 
      <column name="UMTS_ID" /> 
      <generator class="org.hibernate.id.enhanced.SequenceStyleGenerator"> 
       <param name="optimizer">pooled-lo</param> 
       <param name="increment_size">1</param> 
       <param name="sequence_name">UMTS_SEQ</param> 
      </generator> 
     </id> 
     <property name="cid" type="java.lang.Integer"> 
      <column name="CI" not-null="true" /> 
     </property> 
     <property name="channelNo" type="java.lang.Integer"> 
      <column name="UARFCN" /> 
     </property> 
     <property name="signalStrength" type="java.lang.Double"> 
      <column name="EC_IO" precision="53" scale="0" /> 
     </property> 
     <property name="sc" type="java.lang.Integer"> 
      <column name="SC" /> 
     </property> 
     <property name="latitude" type="java.lang.Double"> 
      <column name="LATITUDE" precision="53" scale="0" /> 
     </property> 
     <property name="longitude" type="java.lang.Double"> 
      <column name="LONGITUDE" precision="53" scale="0" /> 
     </property> 
     <property name="mcc" type="java.lang.Integer"> 
      <column name="MCC" not-null="true" /> 
     </property> 
     <property name="mnc" type="java.lang.Integer"> 
      <column name="MNC" not-null="true" /> 
     </property> 
     <property name="recvDate" type="date"> 
      <column name="RECV_DATE" length="10" /> 
     </property> 
     <property name="recvTime" type="time"> 
      <column name="RECV_TIME" length="16" /> 
     </property> 
    </class> 
</hibernate-mapping> 

Service-Klasse:

public void process(List<Umts> umtsList) 
{ 
    for (int i = 0; i < umtsList.size(); i = i + PropertiesUtil.MAX_COMMIT_COUNT) 
     { 
      int min = i; 
      int max = i + PropertiesUtil.MAX_COMMIT_COUNT; 

      if (max > umtsList.size()) 
      { 
       max = umtsList.size(); 
      } 

      createUmts_TransNew(umtsList.subList(min, max)); 
     } 
} 
    @Override 
     public void createUmts_TransNew(Collection list) 
     { 
      // TODO Auto-generated method stub 

      umtsDAO.saveAll(list); 
     } 

DAO Klasse:

@Transactional 
    public void saveAll(Collection collection) 
    { 
     log.debug("** save all"); 
     try 
     { 
      if (collection != null && collection.size() > 0) 
      { 
       for (Object obj : collection) 
       { 
        sessionFactory.getCurrentSession().saveOrUpdate(obj);     
       } 
      } 
     } 
     catch (RuntimeException re) 
     { 
      log.error("** save all failed", re); 
      throw re; 
     } 
    } 

** Herausgegeben Hat Connection-Pool eine Rolle spielt hier? Bedeutung hilft Verbindungspool mit der Leistung? Muss ich die JAR-Datei zur Wildfly 10 oder zur Anwendung selbst hinzufügen?

+0

warum es in Java? Können Sie die Stapeleinfügung verwenden? –

+0

@ScaryWombat ist nicht das, was ich einen Batch-Einsatz gemacht habe? – shadow

+0

siehe http://viralpatel.net/blogs/batch-insert-in-java-jdbc/ –

Antwort

0

Versuchen Sie zunächst, den Wert pooled-lo zu erhöhen. Da Sie ihn auf 1 setzen, wird keine Optimierung/kein Pooling durchgeführt - da jede ID, die abgerufen werden muss, einen Aufruf an die Datenbank benötigt, um den tatsächlichen Wert zu erhalten. Wenn Sie eine größere Inkrementgröße haben, wird der Ruhezustand einen Block von IDs für neue Entitäten vorab abrufen/reservieren, ohne dass ein Entity-Round-Trip erforderlich ist.

Nicht sicher, wie der Code, den Sie veröffentlicht haben, ausgeführt wird, aber ich nehme an, dass Sie sie sequentiell in einen einzelnen Thread einfügen. Sie können:

  • Verwenden Sie einen Thread-Pool, in dem jeder Thread eine Anzahl von Elementen aus der Liste/Warteschlange zum Einfügen nimmt.
  • Die Elemente, die in einer einzelnen Transaktion von einem Thread eingefügt werden, haben im Idealfall die gleiche Größe wie die konfigurierte Ruhezustandsgröße, um wiederum Roundtrips zu minimieren.
  • Stellen Sie sicher, dass die Anzahl der Threads im Pool der Größe des Verbindungspools entspricht, sodass Sie die Worker-Threads beim Warten auf eine Verbindung nicht blockieren.
  • Stellen Sie sicher, dass die Größe des Verbindungspools für die Auslastung Ihres Servers angemessen ist und einen guten Verbindungspool verwendet (z. B. HikariCP). Hier ist eine interessante writeup on connection pool size.
+0

sollte die inkrementelle Größe dem Cache-Wert in db folgen? – shadow

+0

Der Cache-Wert in der MSSQL-Sequenz bestimmt, wie viele Sequenzwerte im Speicher gehalten werden und schreibt nur für jede X-Verwendung in seine Systemtabellen. MSSQL erhöht die Sequenz immer noch um 1, wenn dies vom Ruhezustand angefordert wird, unabhängig von der Cache-Eigenschaft der Sequenz. Also nein, es sollte nicht das gleiche sein, wie es transparent ist, um zu überwintern, wie die internen Folgen in der DB behandelt werden - es sieht die Inkremente nur um 1, wenn es benutzt wird. –

+0

Ich bin immer noch verloren. Auch nach Änderung des Wertes bleibt die Leistung gleich. Muss ich auch HikariCP als Lib in Wildfly 10 oder zu meiner Anwendung selbst hinzufügen? – shadow

Verwandte Themen