数据仓库系列 之使用PreparedStatement执行批量插入sql的三种方式

Posted 琅晓琳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据仓库系列 之使用PreparedStatement执行批量插入sql的三种方式相关的知识,希望对你有一定的参考价值。

使用PreparedStatement(方式一):

@Test
    public void test1() 
        Connection conn = null;
        PreparedStatement ps = null;
        try 
            long start = System.currentTimeMillis();
            conn = DBUtil.getConnection();
            String sql = "insert into table1(`name`) values(?)";
            ps = conn.prepareStatement(sql);
            for (int i = 1; i <= 20000; i++) 
                ps.setString(1, "name_" + i);
                ps.execute();
            
 
            long end = System.currentTimeMillis();
            System.out.println("执行20000条sql共花费" + (end - start) + "毫秒");
         catch (Exception e) 
            e.printStackTrace();
         finally 
            DBUtil.CloseDB(conn, ps);
        
    

使用PreparedStatement相较于Statement在批量插入上的优点:不用每次都去编译sql语句。

使用PreparedStatement的方式二:使用了 addBatch() / executeBatch() / clearBatch()三板斧,batch类似缓冲池,可以先攒一定数量的sql,数量到了我们指定batch的大小然后再批量执行。代码如下:

/*
     * 修改1: 使用 addBatch() / executeBatch() / clearBatch()
     * 修改2:mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。
     * 		 ?rewriteBatchedStatements=true 写在配置文件的url后面
     * 修改3:使用更新的mysql 驱动:mysql-connector-java-5.1.37-bin.jar
     *
     */
 
    @Test
    public void test2() 
        Connection conn = null;
        PreparedStatement ps = null;
        try 
            long start = System.currentTimeMillis();
            conn = DBUtil.getConnection();
            String sql = "insert into table1(`name`) values(?)";
            ps = conn.prepareStatement(sql);
            for (int i = 1; i <= 10000000; i++) 
                ps.setString(1, "name_" + i);
                //ps.execute();
                //1."攒"sql
                ps.addBatch();
                if (i % 500 == 0) 
                    //2.执行Batch
                    ps.executeBatch();
                    //3.清空Batch
                    ps.clearBatch();
                
 
            
 
            long end = System.currentTimeMillis();
            System.out.println("执行一千万条sql共花费" + (end - start) + "毫秒");
         catch (Exception e) 
            e.printStackTrace();
         finally 
            DBUtil.CloseDB(conn, ps);
        
    

使用PreparedStatement的方式三:使用batch批量处理的前提下,设置手动提交,因为每次执行executeBatch会自动提交一次,这里也会涉及与数据库的交互,需要耗费一定的时间,因此我们可以设置手动提交,等执行完所有要批量插入的数据后在手动提交。代码如下:

@Test
    public void test3() 
        Connection conn = null;
        PreparedStatement ps = null;
        try 
            long start = System.currentTimeMillis();
            conn = DBUtil.getConnection();
            //设置为手动提交数据
            conn.setAutoCommit(false);
            String sql = "insert into table1(`name`) values(?)";
            ps = conn.prepareStatement(sql);
            for (int i = 1; i <= 10000000; i++) 
                ps.setString(1, "name_" + i);
                //ps.execute();
                //1.“攒”sql
                ps.addBatch();
                if (i % 500 == 0) 
                    //2.执行Batch
                    ps.executeBatch();
                    //3.清空Batch
                    ps.clearBatch();
                
 
            
            //提交数据
            conn.commit();
 
            long end = System.currentTimeMillis();
            System.out.println("执行一千万条sql共花费" + (end - start) + "毫秒");
         catch (Exception e) 
            e.printStackTrace();
         finally 
            DBUtil.CloseDB(conn, ps);
        
    

三种方式的效率依次递进,当然具体情况还是要分具体应用场景来看。

补充:

关于rewriteBatchedStatements这个参数介绍:
MySQL的JDBC连接的url中要加rewriteBatchedStatements参数,并保证5.1.13以上版本的驱动,才能实现高性能的批量插入。
MySQL JDBC驱动在默认情况下会无视executeBatch()语句,把我们期望批量执行的一组sql语句拆散,一条一条地发给MySQL数据库,批量插入实际上是单条插入,直接造成较低的性能。
只有把rewriteBatchedStatements参数置为true, 驱动才会帮你批量执行SQL。
另外这个选项对INSERT/UPDATE/DELETE都有效。

参考资料:
https://blog.csdn.net/weixin_45861045/article/details/126095061 使用PreparedStatement执行批量插入sql的三种方式以及效率
https://blog.csdn.net/qq_34283987/article/details/107694587 批处理 rewriteBatchedStatements=true

以上是关于数据仓库系列 之使用PreparedStatement执行批量插入sql的三种方式的主要内容,如果未能解决你的问题,请参考以下文章

数据仓库系列 之使用PreparedStatement执行批量插入sql的三种方式

数据仓库系列 之使用PreparedStatement执行批量插入sql的三种方式

数据仓库系列之元数据管理

数据仓库系列之关于数据仓库自动化技术

数据仓库系列之关于数据仓库自动化技术

数据仓库系列之元数据管理系统