老师为什么我tc1()用了批处理的执行出来反而比不用批处理的tc2()慢了

老师为什么我tc1()用了批处理的执行出来反而比不用批处理的tc2()慢了

package com.imooc.jdbc.sample;

import com.imooc.jdbc.common.DbUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;

public class BatchSample {
    public static void tc1(){
        //批量添加1000名员工
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            long startTime = new Date().getTime();
            conn = DbUtils.getConnection();
            String sql = "insert into employee(eno,ename,salary,dname) values(?,?,?,?)";
            pstmt = conn.prepareStatement(sql);
            for(int i=10000;i<20000;i++){
                conn.setAutoCommit(false);
                //若不使用手动提交事务模式,遇到事故时,会出现事情做一半的情况
//                if(i==1005){
//                    throw new RuntimeException("插入失败");
//                }
                pstmt.setInt(1,i);
                pstmt.setNString(2,"员工"+i);
                pstmt.setFloat(3,4000f);
                pstmt.setNString(4,"市场部");
                pstmt.addBatch();//将参数加入批处理
//                pstmt.executeUpdate();
            }
            pstmt.executeBatch();
            conn.commit();//提交数据
            long endTime = new Date().getTime();
            System.out.println("tc1执行时长为"+(endTime-startTime));
        } catch (Exception e) {
            e.printStackTrace();
            try {
                if(conn != null && !conn.isClosed()){
                    conn.rollback();//回滚数据
                }
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
        } finally{
            DbUtils.closeConnection(null,pstmt,conn);
        }
    }
    public static void tc2(){
        //批量添加1000名员工
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = DbUtils.getConnection();
            long startTime = new Date().getTime();
            String sql = "insert into employee(eno,ename,salary,dname) values(?,?,?,?)";
            for(int i=20000;i<30000;i++){
                conn.setAutoCommit(false);
                //若不使用手动提交事务模式,遇到事故时,会出现事情做一半的情况
//                if(i==1005){
//                    throw new RuntimeException("插入失败");
//                }
                pstmt = conn.prepareStatement(sql);
                pstmt.setInt(1,i);
                pstmt.setNString(2,"员工"+i);
                pstmt.setFloat(3,4000f);
                pstmt.setNString(4,"市场部");
                pstmt.executeUpdate();
            }
            conn.commit();//提交数据
            long endTime = new Date().getTime();
            System.out.println("tc2执行时长为"+(endTime-startTime));
        } catch (Exception e) {
            e.printStackTrace();
            try {
                if(conn != null && !conn.isClosed()){
                    conn.rollback();//回滚数据
                }
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
        } finally{
            DbUtils.closeConnection(null,pstmt,conn);
        }
    }

    public static void main(String[] args) {
        tc1();
        tc2();
    }
}

结果:
tc1执行时长为1893
tc2执行时长为1740


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
好帮手慕小蓝 2023-06-12 09:43:13

同学你好~

如果数据库没有对批处理进行配置设置的话,这两种形式的效率是相差无几的,这是因为虽然在JDBC中使用了批处理的形式,提高了在JVM与数据库间的交互速度,但是数据库本身还是以单条的形式进行存储的。

这就导致,虽然JDBC的效率提高了,但是存储速度并没有提高,最终执行的速度也就相差无几了。

同学可以尝试在MySql的URL配置中加入rewriteBatchedStatements=true子句,这个子句可以使得MySql数据库本身也支持批处理形式。

当加入这段配置之后,同学可以再运行一下,效率会有明显的差距。

祝学习愉快~

问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师