如何通过java程序更快地选择和插入百万条记录

Posted

技术标签:

【中文标题】如何通过java程序更快地选择和插入百万条记录【英文标题】:How to do select and insert million records through java program faster 【发布时间】:2016-09-24 13:11:37 【问题描述】:

我正在尝试从 redshift 表中选择大约 100 万条记录,然后需要将这些记录插入 redshift 表(在进行一些操作之后)

但是,这需要很长时间。我等了大约 1 个小时让程序终止,但没有运气。控制台似乎也没有打印print statements,但在打印几条语句后似乎卡住了。

尝试了 100 条记录,效果很好,大约需要 2 分钟。

这是我的代码的一部分:

        conn.setAutoCommit(false);
        stmt = conn.createStatement();
        stmt.setFetchSize(100);
        ResultSet rsSelect = stmt.executeQuery("select * from table");
        System.out.println("select done !");

        String queryInsert = "insert into table"
                +"(event_id,domain_userid,collector_tstamp,se_category,se_action,se_label,se_property)"
                +"values(?,?,?,?,?,?,?)";

        PreparedStatement preparedStatement = conn.prepareStatement(queryInsert);
        final int batchSize = 10000;
        int count = 0;
        System.out.println("about to go into loop !");


        while(rsSelect.next())

            String event_id = rsSelect.getString("event_id");
            String domain_userid = rsSelect.getString("domain_userid");
            Timestamp collector_tstamp = rsSelect.getTimestamp("collector_tstamp");
            String se_category = rsSelect.getString("se_category");
            String se_action = rsSelect.getString("se_action");
            String se_label = rsSelect.getString("se_label");
            String se_property = rsSelect.getString("se_property");

            //some manipulations

            preparedStatement.setString(1, event_id);
            preparedStatement.setString(2, domain_userid);
            preparedStatement.setTimestamp(3, collector_tstamp);
            preparedStatement.setString(4, se_category);
            preparedStatement.setString(5, se_action);
            preparedStatement.setString(6, se_label);                        
            preparedStatement.setString(7, se_property);
            preparedStatement.addBatch(); 

            if(++count % batchSize == 0)
                preparedStatement.executeBatch();
                System.out.println("batch execution!");

                           
        
        System.out.println("out of loop");
        preparedStatement.executeBatch();
        preparedStatement.close();
        conn.commit();
        conn.close();   

【问题讨论】:

***.com/questions/6892105/… 我使用了 bach 插入 @Pradeep 使用 BULK INSERT - 它专为满足您的要求而设计,并显着提高了插入速度。此外,(以防万一您确实没有索引)您可能还需要考虑添加索引 - 一些索引(大多数是主键上的索引)可能会提高插入的性能。您应该能够插入记录的实际速率将取决于确切的数据、表结构以及 SQL 服务器本身的硬件/配置,所以我真的不能给您任何数字。 msdn.microsoft.com/en-us/library/ms188365.aspx 你能用 SQL 进行操作吗?如果是这样,您可以将选择查询的结果直接插入到目标表中。如果无法在 SQL 中进行操作,请将操作数据的结果写入 S3 中的文件并使用 redshift COPY 命令。见docs.aws.amazon.com/redshift/latest/dg/…和docs.aws.amazon.com/redshift/latest/dg/… 【参考方案1】:

我遇到了同样的问题,将数据从一个 redshift 表插入到另一个 redshift 表(我使用了 node.js)花费了太长时间。最初,我花了大约 18 分钟来插入 100 万条记录。 我认为我的表中的数据没有根据排序键(时间戳)排序。必须根据排序键对数据进行排序,并在 where 谓词中使用该排序键(如果您有 where 谓词)。Run vacuum table to 100 percent 对数据进行排序。操作后,请确保根据排序键按数据排序。 这样做之后,我能够达到意想不到的效果。 3 秒内插入 100 万条记录。

【讨论】:

谢谢@Redshift Guy。我一定会试一试并分享结果。

以上是关于如何通过java程序更快地选择和插入百万条记录的主要内容,如果未能解决你的问题,请参考以下文章

在具有数百万条记录的 2 个表上加入更快

Rownum 或 Fetch/offset 适合选择和处理数百万条记录

优化插入数百万条记录,MySQL 和 PHP

将数百万条记录从平面文件插入 SQL Server 的陷阱是啥?

如何优化限制查询以更快地从大表中访问数据?

如何使用 Talend Open Studio 处理数百万条 MongoDB 记录并将其插入 Postgres