洛上言 2023-08-24 19:12 采纳率: 95.4%
浏览 9
已结题

jdbc中的批量操作,我明明都是按照步骤写的,但最后的执行时间并没有优化,这是为什么?

jdbc中的批量操作,我明明都是按照步骤写的,但最后的执行时间并没有优化,这是为什么?

img


完整代码:

/**
     * 使用批量插入的方式插入100000条数据
     * TODO:总结批量插入
     *      1.路径后面添加?rewriteBatchedStatements=true 允许批量插入
     *      2.insert into 必须写values, 语句末尾 不能 添加 “;” 结束
     *      3.不是执行语句每条,是批量添加 addBatch();
     *      4.遍历添加完毕以后,统一批量执行 executeBatch()
     */
    @Test
    public void testBatchInsert() throws Exception {
        //1.注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //2.获取连接
        Connection connection = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/itcast?rewriteBathedStatements=true", "root", "123456");

        //3.编写sql语句
        String sql = "insert into employee(name, salary, departmentId) values(?, ?, ?)";

        //4.创建statement
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //5.占位符赋值
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            preparedStatement.setObject(1, "dd" + i);
            preparedStatement.setObject(2, 5);
            preparedStatement.setObject(3, 2);

//            preparedStatement.executeUpdate();
            preparedStatement.addBatch();//不执行,追加到values后面!
        }
        preparedStatement.executeBatch();//执行批量操作!
        //这里可能会有另外的一个方法:statement.executeLargeBatch();//假的,jdbc里面没有任何操作!!

        long end = System.currentTimeMillis();

        System.out.println("执行100000次数据插入消耗的时间" + (end - start) + "ms");
        //8.关闭资源
        connection.close();
        preparedStatement.close();
    }

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-08-24 22:19
    关注

    【以下回答由 GPT 生成】

    问题标题: 为什么按照步骤操作的jdbc中的批量插入没有提高执行时间?

    问题内容: 我按照以下步骤进行了jdbc中的批量插入操作,但是最后的执行时间并没有提高。为什么会这样呢?

    完整代码如下:

    /**
     * 使用批量插入的方式插入100000条数据
     * TODO: 总结批量插入
     *      1.路径后面添加?rewriteBatchedStatements=true 允许批量插入
     *      2.insert into 必须写values,语句末尾不能添加 “;” 结束
     *      3.不是执行语句每条,是批量添加 addBatch();
     *      4.遍历添加完毕以后,统一批量执行 executeBatch()
     */
    @Test
    public void testBatchInsert() throws Exception {
        // 1.注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
    
        // 2.获取连接
        Connection connection = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/itcast?rewriteBatchedStatements=true", "root", "123456");
    
        // 3.编写sql语句
        String sql = "insert into employee(name, salary, departmentId) values(?, ?, ?)";
    
        // 4.创建statement
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
    
        // 5.占位符赋值
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            preparedStatement.setObject(1, "dd" + i);
            preparedStatement.setObject(2, 5);
            preparedStatement.setObject(3, 2);
    
            // preparedStatement.executeUpdate();
            preparedStatement.addBatch(); // 不执行,追加到values后面!
        }
        preparedStatement.executeBatch(); // 执行批量操作!
        // 这里可能会有另外的一个方法: statement.executeLargeBatch(); // 假的,jdbc里面没有任何操作!!
    
        long end = System.currentTimeMillis();
    
        System.out.println("执行100000次数据插入消耗的时间: " + (end - start) + "ms");
    
        // 8.关闭资源
        connection.close();
        preparedStatement.close();
    }
    

    提示: 请问您在批量插入操作中使用了哪些方法和技巧?您期望的执行时间是多少?是否尝试过其他的优化方法?是否查看了数据库的相关配置?请提供更多的细节和背景信息,以便我们更好地理解和提供帮助。

    回答:

    在上述代码中,使用了JDBC的批量插入操作来插入10000条数据,但奇怪的是执行时间并未提高。

    这是因为在MySQL中,不同的JDBC驱动程序对批量操作的处理方式有所不同。上述代码中使用的MySQL Connector/J驱动程序默认的处理方式是将批量操作拆分为多条单独的SQL语句执行,这导致在执行批量插入时并没有提高执行时间。

    要解决这个问题,可以尝试以下方法和技巧:

    1. 配置JDBC连接URL:在连接URL中添加?rewriteBatchedStatements=true参数,以允许批量插入。例如:jdbc:mysql://localhost:3306/itcast?rewriteBatchedStatements=true

    2. 将插入语句的values关键字后面的多个值拼接成一个长字符串,然后使用PreparedStatementaddBatch()方法将所有的插入语句添加到批量操作中。例如:

    ```java StringBuilder sqlBuilder = new StringBuilder("insert into employee(name, salary, departmentId) values"); for (int i = 0; i < 10000; i++) { sqlBuilder.append("(?, ?, ?),"); } String sql = sqlBuilder.substring(0, sqlBuilder.length() - 1); // 去除最后一个多余的逗号 PreparedStatement preparedStatement = connection.prepareStatement(sql);

    int parameterIndex = 1; for (int i = 0; i < 10000; i++) { preparedStatement.setObject(parameterIndex++, "dd" + i); preparedStatement.setObject(parameterIndex++, 5); preparedStatement.setObject(parameterIndex++, 2); }

    preparedStatement.addBatch(); preparedStatement.executeBatch(); ```

    这种方式将多个插入语句合并为一个语句,可以提高批量插入的性能。

    1. 可以尝试使用Statement.executeLargeBatch()方法,该方法在MySQL Connector/J驱动程序中提供了对大批量操作的支持。但需要注意的是,该方法需要MySQL服务器的版本为5.1.13或更高版本。可以尝试替换preparedStatement.executeBatch()((com.mysql.cj.jdbc.StatementImpl)preparedStatement).executeLargeBatch()

    此外,还可以尝试以下优化方法:

    1. 调整MySQL数据库的相关配置,例如调整innodb_flush_log_at_trx_commitinnodb_buffer_pool_size等参数,以提高数据库性能。

    2. 分析数据库的索引和表结构,确保索引的正确使用,以提高查询和插入的性能。

    3. 使用连接池来管理数据库连接,避免频繁创建和销毁数据库连接的开销。

    最后,还需要确认是否有其他因素影响了批量插入的性能,例如网络延迟、硬件性能等。

    希望以上解决方案对您有帮助。如果还有其他问题,请提供更多细节和背景信息,以便我们更好地理解并提供帮助。



    【相关推荐】



    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 9月2日
  • 已采纳回答 8月25日
  • 创建了问题 8月24日