Javaはオラクルから大量のデータを読み取り、それをファイルに書き込みます

Javaはオラクルから大量のデータを読み取り、それをファイルに書き込みます

背景:プロジェクトは、Oracleからテーブルフィールドを読み取り、指定されたスペーサーでフィールドをスプライスし、txtに出力する必要があります。各テーブルのデータ量は約2000Wです。これは、テーブル内の指定されたフィールドのすべてのデータを読み取るだけでよく、クエリの最適化を考慮する必要がなく、テーブルの読み取りスケールを最適化するだけだからです。

バージョンオラクル11G

アイデア1:

oracleステートメントを使用して、データテーブルをページングします。ここで注意する必要があるのは、rowidとrownumの効率、および


SELECT t.*
  FROM a t, (SELECT ROWNUM rn, c.*
                  FROM (SELECT   ROWID k
                            FROM a
                        ORDER BY ID) c) b
WHERE t.ROWID = b.k AND b.rn BETWEEN 10001 AND 20000;

比較記事があります、あなたはhttp://www.itpub.net/thread-1603830-1-1.htmlを見ることができます

このアイデアも私のニーズには適していません。ページングの読み取りはクエリ時間を短縮しますが、数千万の大きなテーブルの場合、ページングに時間がかかるほど、全体的な効率の向上はあまりありません。 。

アイデア2:

データを書き込むときは、書き込み効率を向上させるために複数のスレッドを使用します。テストにより、効率のボトルネックはデータの書き込みではなく、データの読み取りにあることが証明されています。

アイデア3:

ResultSetを使用して、結果セットをバッチで読み取ります。最初は、ResultSetがバッチ読み取りを直接サポートすることを期待していませんでした。最初の2つのアイデアには多くの時間がかかりました。

コードを貼り付ける前に
まずResultSetの一般的な使用法を説明しくださいクリックして表示

ほとんどの記事では、一般的なメソッドとパラメーター設定について説明しています。ResultSetsetFetchSize()setMaxRows()不足しており、言及する人はほとんどいません

简单来说
setFetchSize()  :是设置ResultSet每次向数据库取的行数 

例如:rs.setFetchSize(100),ResultSet每次向数据库读取100条数据,
之后下一百条数据的读取是在ResultSet内部完成的,不需要手动去进行调用或定位数据从哪行开始。

setMaxRows() :是设置Resultset最多返回的行数,不需要读取全部数据,只要特定行数的数据,可以选择此方法。

記事の分析は
悪くありません:JDBC読み取りデータ最適化setFetchSizeJDBC
読み取りデータ最適化-フェッチサイズ

また、設定されている場合

stmt = destCon.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);

このエラーを報告する可能性があります
ここに写真の説明を挿入

这时需要把 
ResultSet.TYPE_SCROLL_SENSITIVE
改为
ResultSet.TYPE_SCROLL_INSENSITIVE,

以下に私のコードを貼り付けてください


public static void main(String[] args) throws SQLException, ClassNotFoundException, IOException {
    
    

        String selsql;
        Connection destCon = null;
        Statement stmt = null;
        BufferedWriter output = null;
        long rowCount = 0L;
        int colCounts = 0;
        ResultSet res = null;

        long flen = 0L;
        selsql = "select RANDOM_STRING from myTestTable";
        destCon = getConnection();
        int fileCount = 1;
        EtlRuler etlRuler = new EtlRuler();
        etlRuler.setLocal_path("E:\\web_project\\");
        etlRuler.setFile_name("test010.txt");
        String filePath = etlRuler.getLocal_path() + etlRuler.getFile_name().replace("${NUM}", "00" + fileCount);
        etlRuler.getDataPath().add(filePath);


        File file = new File(etlRuler.getDataPath().get(fileCount - 1));
        if (!file.exists()) {
    
    
            file.createNewFile();
        }
        StringBuilder line = new StringBuilder();
        output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, false), StandardCharsets.UTF_8));

        stmt = destCon.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
        res = stmt.executeQuery(selsql);
        res.setFetchSize(2000);



        if (res == null || !res.next()) {
    
    
            System.out.println("数据文件sql无数据!");
            // throw new Exception("数据文件sql无数据!");
        }
        assert res != null;
        res.previous();

        // 获取字段元信息
        ResultSetMetaData rsmd1 = res.getMetaData();
        colCounts = rsmd1.getColumnCount();
        int j = 0;
        String str = "";
        while (res.next()) {
    
    
            //System.out.println("开始读取数据" + rowCount++);
            // 打印进度
            rowCount++;
            if (rowCount % 2000 == 0) {
    
    
                Date date = new Date();
                //20w条数据的时候写入一下,之后清空StringBuilder,重新添加数据
                System.out.println("执行时间:" + date);
                System.out.println(rowCount + " ----rows proceed");
//                output.write(line.toString());
//                output.flush();
//                line.delete(0, line.length());
            }

            for (int i = 1; i <= colCounts; i++) {
    
    
                //line.append(res.getString(i)).append("\n");
                str = res.getString(i)+"\n";
            }
            output.write(str);
            output.flush();
            str = "";

            //System.out.println("开始写入数据");


            if (file.length() > (1024 * 500)) {
    
    
                if (etlRuler.getFile_name().contains("${NUM}")) {
    
    
                    //output.write(line.toString());
                    //output.flush();
                    //line.delete(0,line.length());
                    fileCount++;
                    System.out.println("创建新文件");
                    String newfilePath = etlRuler.getLocal_path() + etlRuler.getFile_name().replace("${NUM}", "00" + fileCount);
                    etlRuler.getDataPath().add(newfilePath);
                    file = new File(etlRuler.getDataPath().get(fileCount - 1));
                    if (!file.exists()) {
    
    
                        file.createNewFile();
                    }
                    output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, false),
                            StandardCharsets.UTF_8));
                }
            }
        }

        //System.out.println("开始写入数据");
        output.write(line.toString());
        output.flush();
        output.close();
        flen = file.length();
        System.out.println("文件大小:" + flen);
    }

public static Connection getConnection() throws ClassNotFoundException, SQLException {
    
    
        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection con = null;
        con = DriverManager.getConnection(
                "jdbc:oracle:thin:@" + ip + ":" + port + ":" + sid, user,
                password);  //设置数据库连接字符串
        return con;
    }

おすすめ

転載: blog.csdn.net/zhuyin6553/article/details/108593447