• 【Jdbc/Oracle】一个用于创建大表并填充批量数据的类 给31字段表填充千万数据约需3040分钟


    这个类是我用来做数据迁移测试的,里面把删表、建表、充值都融合到了一起,字段采用f1,f2,f3...fn的方式递增,字段类型除id外都是nvarchar2,填充的都是固定数据,大家拿下去后可以根据自己的需求修改。

    速度方面,在我的老伙计T440p上,

    如果是31个字段,一千万条数据,用BATCH_SIZE控制十万提交一次,大约需要38分钟;

    同样是31个字段,一千万条数据,控制 五十万提交一次,大约需要33分钟。

    下面是代码:

    package com.hy.lab.inject;
    
    import java.sql.*;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class BigtableInjecter {
        //-- 以下为连接Oracle数据库的四大参数
        private static final String DRIVER = "oracle.jdbc.driver.OracleDriver";
        private static final String URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
        private static final String USER = "luna";
        private static final String PSWD = "1234";
        private static final int    BATCH_SIZE=100000;
    
        /**
         * 创建一张大表
         * @param tableName 表名
         * @param colCnt 除id之外的列数
         * @param rowCnt 记录数
         * @return
         */
        public boolean buildTable(String tableName,int colCnt,int rowCnt){
            List<String> columns=new ArrayList<>();
            for(int i=0;i<colCnt;i++){
                String columnName="F"+(i+1);
                columns.add(columnName);
            }
    
            // Create Table sql
            StringBuilder sb=new StringBuilder();
            sb.append(String.format("create table %s(",tableName));
            sb.append("    id number(12),");
            for(String column:columns){
                sb.append(String.format("%s nvarchar2(20),",column));
            }
            sb.append("    primary key(id)");
            sb.append(")");
            String createTableSql=sb.toString();
            //System.out.println(createTableSql);
    
            // Create Insert Sql
            String[] asks=new String[colCnt];
            for(int i=0;i<colCnt;i++){
                asks[i]="?";
            }
            String insertSql=String.format("insert into %s(id,%s) values(?,%s)",tableName,String.join(",",columns),String.join(",",asks));
    
            Connection conn = null;
            Statement stmt = null;
            PreparedStatement pstmt = null;
    
            try{
                Class.forName(DRIVER);
                conn = DriverManager.getConnection(URL, USER, PSWD);
                stmt = conn.createStatement();
    
                // drop table if exists
                if(isTableExist(tableName,conn)){
                    System.out.println(String.format("发现表%s已存在",tableName));
                    String dropSql=String.format("drop table %s",tableName);
                    stmt.execute(dropSql);
                    System.out.println(String.format("表%s已删除",tableName));
                }else{
                    System.out.println(String.format("发现表%s不存在,无需删除",tableName));
                }
    
                // create table
                stmt.execute(createTableSql);
                System.out.println(String.format("表%s已建成",tableName));
    
                conn.setAutoCommit(false);
                pstmt = conn.prepareStatement(insertSql);
                final String FIX_STRING="ABCDEFGHIJ0123456789";
    
                int count=0;
                int submitCount=0;
                for(int i=0;i<rowCnt;i++){
                    pstmt.setLong(1,i);
                    for(int j=0;j<colCnt;j++){
                        pstmt.setString(j+2,FIX_STRING);
                    }
    
                    pstmt.addBatch();
    
                    count++;
                    if(count>BATCH_SIZE){
                        pstmt.executeBatch();
                        conn.commit();
                        count=0;
    
                        submitCount++;
                        System.out.println(String.format("第%-3d次提交",submitCount));
                    }
                }
    
                pstmt.executeBatch();
                conn.commit();
                submitCount++;
                System.out.println(String.format("第%-3d次提交",submitCount));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    stmt.close();
                    pstmt.close();
                    conn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
            return true;
        }
    
        private boolean isTableExist(String tablename,Connection conn) throws Exception{
            DatabaseMetaData meta= conn.getMetaData();
    
            ResultSet set=meta.getTables(null,null,tablename.toUpperCase(),null);
            if(set.next()){
                return true;
            }
    
            return false;
        }
    
        public static void main(String[] args){
            long startMs=System.currentTimeMillis();
    
            BigtableInjecter injecter=new BigtableInjecter();
            injecter.buildTable("emp_30",30,10000000);
    
            long endMs=System.currentTimeMillis();
            System.out.println("Time elapsed:"+ ms2DHMS(startMs,endMs));
        }
    
        private static String ms2DHMS(long startMs, long endMs) {
            String retval = null;
            long secondCount = (endMs - startMs) / 1000;
            String ms = (endMs - startMs) % 1000 + "ms";
    
            long days = secondCount / (60 * 60 * 24);
            long hours = (secondCount % (60 * 60 * 24)) / (60 * 60);
            long minutes = (secondCount % (60 * 60)) / 60;
            long seconds = secondCount % 60;
    
            if (days > 0) {
                retval = days + "d" + hours + "h" + minutes + "m" + seconds + "s";
            } else if (hours > 0) {
                retval = hours + "h" + minutes + "m" + seconds + "s";
            } else if (minutes > 0) {
                retval = minutes + "m" + seconds + "s";
            } else if(seconds > 0) {
                retval = seconds + "s";
            }else {
                return ms;
            }
    
            return retval + ms;
        }
    }

    输出:

    C:\Java17\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.3.2\lib\idea_rt.jar=60327:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.3.2\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\ufo\IdeaProjects\dataMigration2\target\classes;C:\Users\ufo\.m2\repository\org\springframework\boot\spring-boot-starter\2.6.4\spring-boot-starter-2.6.4.jar;C:\Users\ufo\.m2\repository\org\springframework\boot\spring-boot\2.6.4\spring-boot-2.6.4.jar;C:\Users\ufo\.m2\repository\org\springframework\spring-context\5.3.16\spring-context-5.3.16.jar;C:\Users\ufo\.m2\repository\org\springframework\spring-aop\5.3.16\spring-aop-5.3.16.jar;C:\Users\ufo\.m2\repository\org\springframework\spring-beans\5.3.16\spring-beans-5.3.16.jar;C:\Users\ufo\.m2\repository\org\springframework\spring-expression\5.3.16\spring-expression-5.3.16.jar;C:\Users\ufo\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.6.4\spring-boot-autoconfigure-2.6.4.jar;C:\Users\ufo\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.6.4\spring-boot-starter-logging-2.6.4.jar;C:\Users\ufo\.m2\repository\ch\qos\logback\logback-classic\1.2.10\logback-classic-1.2.10.jar;C:\Users\ufo\.m2\repository\ch\qos\logback\logback-core\1.2.10\logback-core-1.2.10.jar;C:\Users\ufo\.m2\repository\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;C:\Users\ufo\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.17.1\log4j-to-slf4j-2.17.1.jar;C:\Users\ufo\.m2\repository\org\apache\logging\log4j\log4j-api\2.17.1\log4j-api-2.17.1.jar;C:\Users\ufo\.m2\repository\org\slf4j\jul-to-slf4j\1.7.36\jul-to-slf4j-1.7.36.jar;C:\Users\ufo\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\ufo\.m2\repository\org\springframework\spring-core\5.3.16\spring-core-5.3.16.jar;C:\Users\ufo\.m2\repository\org\springframework\spring-jcl\5.3.16\spring-jcl-5.3.16.jar;C:\Users\ufo\.m2\repository\org\yaml\snakeyaml\1.29\snakeyaml-1.29.jar;C:\Users\ufo\.m2\repository\com\alibaba\fastjson\1.2.48\fastjson-1.2.48.jar;C:\Users\ufo\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.12.4\jackson-databind-2.12.4.jar;C:\Users\ufo\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.12.4\jackson-annotations-2.12.4.jar;C:\Users\ufo\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.12.4\jackson-core-2.12.4.jar;C:\Users\ufo\.m2\repository\com\oracle\database\jdbc\ojdbc8\21.1.0.0\ojdbc8-21.1.0.0.jar;C:\Users\ufo\.m2\repository\com\oracle\database\nls\orai18n\21.1.0.0\orai18n-21.1.0.0.jar com.hy.lab.inject.BigtableInjecter
    发现表emp_30已存在
    表emp_30已删除
    表emp_30已建成
    第1  次提交
    第2  次提交
    第3  次提交
    第4  次提交
    第5  次提交
    第6  次提交
    第7  次提交
    第8  次提交
    第9  次提交
    第10 次提交
    第11 次提交
    第12 次提交
    第13 次提交
    第14 次提交
    第15 次提交
    第16 次提交
    第17 次提交
    第18 次提交
    第19 次提交
    第20 次提交
    第21 次提交
    第22 次提交
    第23 次提交
    第24 次提交
    第25 次提交
    第26 次提交
    第27 次提交
    第28 次提交
    第29 次提交
    第30 次提交
    第31 次提交
    第32 次提交
    第33 次提交
    第34 次提交
    第35 次提交
    第36 次提交
    第37 次提交
    第38 次提交
    第39 次提交
    第40 次提交
    第41 次提交
    第42 次提交
    第43 次提交
    第44 次提交
    第45 次提交
    第46 次提交
    第47 次提交
    第48 次提交
    第49 次提交
    第50 次提交
    第51 次提交
    第52 次提交
    第53 次提交
    第54 次提交
    第55 次提交
    第56 次提交
    第57 次提交
    第58 次提交
    第59 次提交
    第60 次提交
    第61 次提交
    第62 次提交
    第63 次提交
    第64 次提交
    第65 次提交
    第66 次提交
    第67 次提交
    第68 次提交
    第69 次提交
    第70 次提交
    第71 次提交
    第72 次提交
    第73 次提交
    第74 次提交
    第75 次提交
    第76 次提交
    第77 次提交
    第78 次提交
    第79 次提交
    第80 次提交
    第81 次提交
    第82 次提交
    第83 次提交
    第84 次提交
    第85 次提交
    第86 次提交
    第87 次提交
    第88 次提交
    第89 次提交
    第90 次提交
    第91 次提交
    第92 次提交
    第93 次提交
    第94 次提交
    第95 次提交
    第96 次提交
    第97 次提交
    第98 次提交
    第99 次提交
    第100次提交
    Time elapsed:38m51s375ms
    
    Process finished with exit code 0

    执行完后表中数据量:

    SQL> select count(*) from emp_30;
    
      COUNT(*)
    ----------
      10000000

    END

  • 相关阅读:
    luogu 1865 数论 线性素数筛法
    洛谷 2921 记忆化搜索 tarjan 基环外向树
    洛谷 1052 dp 状态压缩
    洛谷 1156 dp
    洛谷 1063 dp 区间dp
    洛谷 2409 dp 月赛题目
    洛谷1199 简单博弈 贪心
    洛谷1417 烹调方案 dp 贪心
    洛谷1387 二维dp 不是特别简略的题解 智商题
    2016 10 28考试 dp 乱搞 树状数组
  • 原文地址:https://www.cnblogs.com/heyang78/p/16041415.html
Copyright © 2020-2023  润新知