Hibernate + MySQL简单批量插入速度极慢

时间:2016-08-24 23:42:24

标签: java mysql hibernate orm

我正在将来自Hibernate的2500条记录插入一个完全空的MySQL表中。插件需要5分钟!

我用谷歌搜索了几个小时,尝试了一些像自动生成的主键,但似乎没有什么能改善性能。

我的程序的早期版本是同时进行插入(每个线程1个,大约100个线程),这需要大约2分钟。我认为批处理可以提高性能约10倍,但似乎已经适得其反。

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

这就是我的表格(只有DB中的表格):

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>

1 个答案:

答案 0 :(得分:7)

找到answer here.

rewriteBatchedStatements=true添加到我的JDBC网址中修复它!

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

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