2015-04-23 66 views
1

我需要使用Apache POI将600-700K记录写入xlsx文件。 我目前使用的代码是:性能:使用Java,Apache-POI将Oracle ResultSet写入XLSX

public void writeRecords(ResultSet rs) { 
      try{ 

      SXSSFWorkbook wb = new SXSSFWorkbook(); 
      wb.setCompressTempFiles(true); 

      SXSSFSheet sh = (SXSSFSheet)wb.createSheet("Sheet 1"); 
      Row row = null; 


      int numColumns = rs.getMetaData().getColumnCount(); 

       // Workbook wb = ExcelFileUtil.createExcelWorkBook(true, 5); 


       sh.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk 
       Row heading = sh.createRow(1); 

       ResultSetMetaData rsmd = rs.getMetaData(); 

       for(int x = 0; x < numColumns; x++) { 
        Cell cell = heading.createCell(x+1); 
        cell.setCellValue(rsmd.getColumnLabel(x+1)); 
       } 

       int rowNumber = 2; 
       int sheetNumber = 0; 

       while(rs.next()) { 

        row = sh.createRow(rowNumber); 
        for(int y = 0; y < numColumns; y++) { 
         row.createCell(y+1).setCellValue(rs.getString(y+1)); 
         // wb.write(bos); 
        } 

        rowNumber++; 
       } 

       FileOutputStream out = new FileOutputStream("C:/Users/test1.xlsx"); 
       wb.write(out); 
       out.close(); 
      } 
       catch (Exception e){ 
        e.printStackTrace(); 

       } 

它工作正常,但它走约50分钟的时间写〜65K的记录。65分钟记录的结果集在5-6分钟内被提取。

有什么办法可以在10-15分钟内用POI写出600,000-700,000条记录 。 我们无法将数据导出为CSV格式,因为最终用户只能导入xlsx文件。 关于, Tushar

+1

运行你怎么知道的ResultSet在7秒内是牵强?在上面的代码中,您仍然在写入行时进行提取。 – Thilo

+0

另外,如果Excel将700k行的电子表格放在电子表格中,Excel的行为如何?那个文件有多大? – Thilo

+0

我之前和之后记录的时间戳:\t ps = con.prepareStatement(“select * from table_1 where rownum <65000”); \t \t rs = ps.executeQuery(); – Tushar

回答

3

检查PreparedStatement的fetchSize。如果没有明确设置,则与表格的实际情况相比,该值可能非常小,并且大中型数据的查询速度看起来很非常影响

Check this question欲了解更多信息。

此外,请考虑是否有必要根本使用setCompressTempFilesSXSSFWorkbook。如果需要,内存中的行值将以成比例的方式影响性能。

0

如果你能够写入文件输出形式为sqlplus,这将是非常快的。

创建文件,如下mycsv.sql:

SET DEFINE OFF 
    SET ECHO OFF 
    SET SERVEROUTPUT OFF 
    SET TERMOUT OFF 
    SET VERIFY OFF 
    SET FEEDBACK OFF 
    SET PAGESIZE 10000 
    SET ARRAYSIZE 5000 
    REM SET HEAD OFF 
    SET LINE 500 
    spool /tmp/mycsvfile.csv; 
    select * from MY_table; 
    spool off; 
    exit; 

和Linux的提示,你可以像

$> sqlplus username/password @/tmp/mycsv.sql 
+0

根本不回答问题。 – rpax

+0

嗨,我的意思是,你最终的目标是在一个文件中写输出,然后使用sqlplus。这样做sqlplus会更快 – Ramki

+1

嗨。我的意思是,如果你的最终目标是在一个文件中写入csv输出,然后使用sqlplus。 1.在sqlplus中执行会更快。 2.如果Apache中的数据非常高,则可能出现内存不足错误。 3.从数据库获取数据到Apache并写入一个文件,我说的是删除中间的Apache层,这将是很好的优势。我希望这很清楚。 – Ramki