当前位置: 首页 > 面试题库 >

带有HIBERNATE的JPA插入速度非常慢

陆英毅
2023-03-14
问题内容

我正在尝试通过使用JAP和HIBERNATE向SQL Server 2008
R2插入一些数据。一切都“正常”,除了它非常慢。要插入20000行,大约需要45秒,而C#脚本大约需要不到1秒。

这个领域的任何资深人士都可以提供帮助吗?我会很感激。

更新:从下面的答案中得到了一些很好的建议,但仍然无法按预期工作。速度是一样的。

这是更新的persistence.xml:

<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="ClusterPersist"
    transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>cluster.data.persist.sqlserver.EventResult</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="javax.persistence.jdbc.url"
            value="jdbc:sqlserver://MYSERVER:1433;databaseName=MYTABLE" />
        <property name="javax.persistence.jdbc.user" value="USER" />
        <property name="javax.persistence.jdbc.password" value="PASSWORD" />
        <property name="javax.persistence.jdbc.driver"
            value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
        <property name="hibernate.show_sql" value="flase" />
        <property name="hibernate.hbm2ddl.auto" value="update" />

        <property name="hibernate.connection.provider_class"
            value="org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider" />

        <property name="hibernate.c3p0.max_size" value="100" />
        <property name="hibernate.c3p0.min_size" value="0" />
        <property name="hibernate.c3p0.acquire_increment" value="1" />
        <property name="hibernate.c3p0.idle_test_period" value="300" />
        <property name="hibernate.c3p0.max_statements" value="0" />
        <property name="hibernate.c3p0.timeout" value="100" />
        <property name="hibernate.jdbc.batch_size" value="50" />
        <property name="hibernate.cache.use_second_level_cache" value="false" />
    </properties>
</persistence-unit>

这是更新的代码部分:

public static void writeToDB(String filePath) throws IOException {

    EntityManager entityManager = entityManagerFactory.createEntityManager();
    Session session = (Session) entityManager.getDelegate();
    Transaction tx = session.beginTransaction();
    int i = 0;

    URL filePathUrl = null;
    try {
        filePathUrl = new URL(filePath);
    } catch (MalformedURLException e) {
        filePathUrl = (new File(filePath)).toURI().toURL();
    }

    String line = null;
    BufferedReader stream = null;

    try {
        InputStream in = filePathUrl.openStream();
        stream = new BufferedReader(new InputStreamReader(in));


        // Read each line in the file
        MyRow myRow = new MyRow();
        while ((line = stream.readLine()) != null) {
            String[] splitted = line.split(",");
            int num1 = Integer.valueOf(splitted[1]);
            float num2= Float.valueOf(splitted[6]).intValue();

            myRow.setNum1(num1);
            myRow.setNum2(num2);

            session.save(myRow);

            if (i % 50 == 0) { 
                session.flush();
                session.clear();
            }

            i++;

        }
        tx.commit();

    } finally {
        if (stream != null)
            stream.close();
    }
    session.close();

}

已更新,这是MyRow的来源:

@Entity
@Table(name="MYTABLE")
public class MyRow {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY) 
private Long id;

@Basic
@Column(name = "Num1")
private int Num1;

@Basic
@Column(name = "Num2")
private float Num2;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public float getNum1() {
    return Num1;
}

public void setNum1(float num1) {
    Num1 = num1;
}

public int getNum2() {
    return Num2;
}

public void setNum2(int num2) {
    Num2 = num2;
}
}

问题答案:

要启用JDBC批处理,您应该将hibernate.jdbc.batch_size属性初始化为10到50之间(仅int)

hibernate.jdbc.batch_size=50

如果它仍然不如预期的那么快,那么我将回顾上面的文档,同时注意“注意”和第4.1节。特别是提示:“如果使用身份标识符生成器,​​则Hibernate会透明地禁用JDBC级别的插入批处理。”



 类似资料:
  • 问题内容: 我正在尝试通过使用JAP和HIBERNATE向SQL Server 2008 R2插入一些数据。一切都“正常”,除了它非常慢。要插入20000行,大约需要45秒,而C#脚本大约需要不到1秒。 这个领域的任何资深人士都可以提供帮助吗?我会很感激。 更新:从下面的答案中得到了一些很好的建议,但仍然无法按预期工作。速度是一样的。 这是更新的persistence.xml: 这是更新的代码部分

  • 问题内容: 我面临一个非常奇怪的问题:使用Redis时,我的写入速度非常糟糕(在理想情况下,写入速度应该接近RAM上的写入速度)。 这是我的基准: 是生成随机字符串的类(arg是字符串长度) 以下是几个结果: [写入] nb:100000 |时间:4.408319378 |速度:0.713905907055318 MB / s [写入] nb:100000 |时间:4.4139469070553

  • 问题内容: 我有一个表实体映射为: 当我尝试在数据库中插入新记录时,表名被小写转换为:items_to_register,但是我的表名是ITEMS_TO_REGISTER如何在不更改MySql配置的情况下解决问题?(my.cnf) 我在application.properties文件中: 问题答案: 在hibernate5上,它将是 在您的 application.properties 文件中。

  • 我正在尝试读取包含700K条记录的Excel文件,并将这些记录批量插入MySQL数据库表中。 请注意,Excel解析速度很快,我可以在50秒左右的时间内将实体对象放入中。 我使用Spring Boot和Spring数据JPA。 下面是我的部分文件: 以及我的部分: 以下是我的 : 下面是类: 有人能告诉我我在这里做了什么不正确的事情吗? 编辑: 进程未完成并最终抛出错误:- 谢谢

  • 我有Spring启动应用程序与三个弹性搜索群集(ES v6.4.2)配置。application.properties文件如下(我为每个集群配置了三个主节点,但为了简单起见,这里显示了一个): 对于每个集群,我都有一个单独的配置类,在其中设置TransportClient和ElasticsearchTemplate。 现在,当我在本地计算机上运行所有三个集群的情况下本地启动应用程序时,应用程序会正

  • 我将Spring Boot与Hibernate结合使用,为一个简单的web应用程序创建RESTful API,在该应用程序中,我读取一个。csv文件,并将每一行插入到mysql数据库表中。我能够成功地做到这一点,但它需要很长的时间为任何大的csv文件。我明白最好对insert语句进行批处理,以减少事务的数量,但我不认为我用当前的代码实现了这一点。这是我目前正在做的(工作,但非常缓慢): csvup