有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

MySQL使用Java从文件插入大型数据集

我需要将大约180万行从CSV文件插入MySQL数据库。(只有一张桌子)

目前正在使用Java解析文件并插入每一行

正如你所能想象的,这需要相当多的时间来运行。(十)

我没有将数据从文件直接导入数据库的原因是,在将数据添加到数据库之前,必须对数据进行操作

这个过程需要由IT经理在那里运行。因此,我将其设置为一个很好的批处理文件,以便在将新csv文件放入正确位置后运行。因此,我需要通过将文件放到某个位置并运行批处理文件来很好地完成这项工作。(Windows环境)

我的问题是,插入这么多数据的最快方式是什么;大插入,从临时解析文件还是一次插入一个?可能还有别的想法吗

第二个问题是,如何优化MySQL安装以允许非常快速的插入。(在某一点上,还需要对所有数据进行大量选择)

注意:该表最终将被删除,整个过程将在稍后再次运行

一些澄清: 目前正在使用。。。opencsv。CSVReader解析文件,然后在每一行上进行插入。不过,我对一些专栏进行了浓缩,而忽略了其他专栏

进一步澄清: 本地数据库 MyISAM表


共 (6) 个答案

  1. # 1 楼答案

    您是否绝对确定已经在JDBC驱动程序中禁用了自动提交

    这是JDBC客户端的典型性能杀手

  2. # 2 楼答案

    为此,您应该在MySQL控制台上使用加载数据,而不是通过代码

    LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
    

    如果您需要操纵数据,我仍然建议您在内存中操纵,重写为平面文件,并使用LOAD data将其推送到数据库,我认为这样应该更有效

  3. # 3 楼答案

    另一个想法:是否使用PreparedStatement插入JDBC中的数据

  4. # 4 楼答案

    我可能会选择一个很大的数字,比如10k行,然后从CSV加载那么多行,对数据进行处理,并进行批量更新,然后重复,直到完成整个CSV。根据按摩/数据量,1.8 mil行不应花费10小时,更像是1-2小时,具体取决于您的硬件

    编辑:哎哟,遗漏了一个相当重要的部分,你的con必须将autocommit设置为false,我从中复制的代码是作为GetConnection()方法的一部分来执行的

        Connection con = GetConnection();
    con.setAutoCommit(false);
                try{
                    PreparedStatement ps = con.prepareStatement("INSERT INTO table(col1, col2) VALUES(?, ?)");
                    try{
                        for(Data d : massagedData){
                            ps.setString(1, d.whatever());
                                            ps.setString(2, d.whatever2());
                                                ps.addBatch();
                        }
                        ps.executeBatch();
                    }finally{
                        ps.close();
                    }
                }finally{
                    con.close();
                }
    
  5. # 5 楼答案

    快速插入提示:

    • 使用LOAD DATA INFILE语法让MySQL解析并插入它,即使您必须在操作后将其撕碎并馈送
    • 使用此插入语法:

      在表(col1,col2)中插入值(val1,val2),(val3,val4)

    • 插入前删除所有键/索引

    • 在你拥有的速度最快的机器上完成(主要是IO,但RAM和CPU也很重要)。无论是DB服务器,还是插入客户端,请记住,您将支付两倍的IO价格(一次读取,第二次插入)
  6. # 6 楼答案

    根据插入数据之前您需要对数据进行的具体操作,您在速度方面的最佳选择是:

  7. 用java解析文件/对数据执行所需操作/将“经过处理”的数据写入新的CSV文件/在该文件上使用“加载数据填充”
  8. 如果您的数据操作是有条件的(例如,您需要检查记录是否存在,并根据是插入还是和更新等执行不同的操作)那么(1)可能是不可能的。在这种情况下,最好进行批量插入/更新
    尝试找到适合您的最佳批量(从大约500-1000开始就可以了)。根据您用于表的存储引擎的不同,您可能还需要将其拆分为多个事务—使用一个跨180万行的存储引擎不会对性能产生任何影响