打印数百万行 / JAVA堆空间

3
我正在处理一些数据库,并需要将每个数据库打印到文件中。我的服务器有5GB的RAM,我为Tomcat服务器分配了4GB。
我使用一个简单的结果集来查询每个数据库的所有行。然后我将每行打印到一个文件中(.dat文件),显然我是分开进行的。
我可以使用包含5738095行的整个结果集工作。
但如果我想处理超过700万行的数据库,我会出现"Java heap space"错误。当我开始处理超过300万行时,我需要向我的服务器添加更多的RAM,因此我的问题是:是将更多的RAM放入我的服务器好呢,还是如何将结果集分成每百万条打印,以避免出现"java heap space"错误。
我一直在考虑计算整个数据库并制定类似于limit 0 offset 1000000、limit 1000000 offset 1000001的东西,但老实说我很困惑。谢谢您的阅读和帮助,也对我的英语表示歉意。
以下是代码:
//numero columnas is the total of columns
 rs_datos =  StDatos.executeQuery("select * from table");
  while(rs_datos.next())
  {

    for(int i = 0; i < numeroColumnas; i++)
    {
      if(i+1 == numeroColumnas)
      {
       pw.print(rs_datos.getString(i+1));
      }
      else
      pw.print(rs_datos.getString(i+1) + "|");
    }

     pw.println("");
  }

  pw.close();

3
无论你拥有多少内存(或少),都不应该影响。一个正确编写的循环只是将一些数据库结果导入文件,不应该占用4GB的内存,除非你正在处理某些巨大的 blob 记录。 - Marc B
2
你使用哪个数据库? - user3467273
MySQL / JSP + JDBC。 - zickno
5个回答

4
您不必将所有行读入RAM以打印它们。连接到数据库,执行您的选择并在迭代结果集时逐行打印。百万行没什么问题,相信我。
您当然也可以使用分页,但在您的情况下,您可能甚至不需要这种方法。
最后一点,我真的不明白为什么您要自己实现此类数据库导出功能。所有数据库都有这样的实用程序可供使用。例如,对于MySQL,可以使用mysqldump。只需找到适用于您的数据库的这样的实用程序并组成正确的命令行参数即可。

我执行了查询,然后当我拥有整个结果集时,将其打印到文件中。我不知道如何“正确地”不将所有结果集都加载到RAM中,但是谢谢,我会寻找其他工具来完成我的工作。 - zickno
@zickno,您还没有展示您的代码,所以很难帮助您。请展示您的代码片段,我们可能能够给您更好的建议。 - AlexR

2
在您当前的设置中,当您调用SQL查询时,检查实际从数据库加载了多少行。参见:Statement.setFetchSize。如果您的JDBC驱动程序支持,应尝试利用延迟加载。
另请参阅:Java JDBC懒加载ResultSet
所以我的意思是,您打算使用LIMITOFFSET做什么,JDBC驱动程序已经可以为您完成。

0
如果您需要备份特定的表格,只需在命令行中执行mysqldump即可:
mysqldump -u... -p... mydb mytable > my_backup.sql

很可能您的程序不够高效,因此一个简单的解决方法是使用这种方法。

-1

您可以从应用程序或cron执行命令,并使用此命令以csv格式创建文档 CSV格式的Mysqldump


-1

给我分数,朋友。

mysqldump -u 用户名 -p 数据库名称 表1名称 > dump.sql


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接