2016-08-24 118 views
0

我从Hibernate插入2500条记录到一个完全空的MySQL表中。插入需要5分钟!Hibernate + MySQL简单批量插入极其缓慢

我已经搜索了几个小时,并尝试了一些东西,如自动生成的主键,但似乎没有提高性能。

我的程序的早期版本是在同时插入(每线程约1个线程约100个线程),并花费了大约2分钟。我认为配料应该将性能提高10倍左右,但它似乎已经不起作用。

我使用Google Cloud's MySQLdb-f1-micro instance

这是我的表看起来像(仅在数据库表!):

CREATE TABLE `categories` (
`browse_node` varchar(60) NOT NULL, 
`name` varchar(60) DEFAULT NULL, 
`path` varchar(400) DEFAULT NULL, 
`url` varchar(200) NOT NULL, 
`level` int(11) NOT NULL, 
PRIMARY KEY (`browse_node`) 
) 

这是POJO:

package example.com; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.Table; 

/** 
* Represents a category from the categories table 
*/ 
@Entity 
@Table(name = "categories") 
public class Category { 

    @Id 
    @Column(name = "browse_node") 
    private String browseNode; 
    @Column(name = "name") 
    private String name; 
    @Column(name = "path") 
    private String path; 
    @Column(name = "url") 
    private String url; 
    @Column(name = "level") 
    private int level; 

    public Category() { 

    } 

    public Category(String browseNode, String name, String path, String url, int level) { 
     this.browseNode = browseNode; 
     this.name = name; 
     this.path = path; 
     this.url = url; 
     this.level = level; 
    } 
    // Omitting setters/getters 
} 

这里是做插入的代码:

private static void writeCategoriesToDb(Map<String, Category> categories) { 
    StatelessSession session = sessionFactory.openStatelessSession(); 
    // Session session = sessionFactory.openSession(); 
    session.beginTransaction(); 

    int i = 0; 
    int batchSize = 50; 

    for (Category category : categories.values()) { 
     session.insert(category); 
//  if (i % batchSize == 0) { 
//   session.flush(); 
//   session.clear(); 
//  } 
//  i++; 
    } 

    session.getTransaction().commit(); 
    session.close(); 
} 

而这里的配置文件:

<?xml version='1.0' encoding='utf-8'?> 
<!DOCTYPE hibernate-configuration PUBLIC 
     "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 

<hibernate-configuration> 
    <session-factory> 

     <!-- Database connection settings --> 
     <property name="connection.driver_class">com.mysql.jdbc.Driver</property> 
     <property name="connection.url">jdbc:mysql://someIp/myDB</property> 
     <property name="connection.username">root</property> 
     <property name="connection.password">password</property> 
     <property name="connection.useSSL">false</property> 
     <!-- JDBC connection pool (use the built-in) --> 
     <property name="connection.pool_size">20</property> 
     <property name="hibernate.jdbc.batch_size">3000</property> 
     <property name="hibernate.id.new_generator_mappings">false</property> 
     <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 

     <!-- Echo all executed SQL to stdout --> 
     <property name="show_sql">true</property> 

     <mapping class="example.com.Category"/> 
    </session-factory> 
</hibernate-configuration> 

回答

6

找到了answer here.

添加rewriteBatchedStatements=true我的JDBC网址定了!

现在需要〜2.2秒来插入所有记录。

<property name="connection.url">jdbc:mysql://someIp/myDB?rewriteBatchedStatements=true</property> 
+0

很好 - 重要的是通过点击管道来接受您的答案,以显示未来的谷歌,这个问题已经得到了回答。 – peterh