2016-11-30 28 views
1

我有一个Java程序,我在一个循环内的SQLite数据库上执行数千次查询。如果查询显示为空,则插入该行。如果查询有结果,我会忽略。我通常以1000个批次执行这些单个查询,但最终会有几十万个查询来完成此任务。Java sqlite执行数千个查询

因为我有数千行我正在用个人查询进行检查,所以这部分程序运行非常缓慢。

是否有更高效的方式来执行这么多的查询?

这里是一个不断拉从Excel文档的原始数据,直到所有的循环中的信息阅读:

for(int i =0;i < batchSize;i++){ 
    try { 
     String[] rowReader=(dataRows.get(i)); 
     archiveID=rowReader[16]; 
     DIVA = rowReader[41]; 

     //Check if already in DB. If it is not, then adds to a batch 
     System.out.println("checking db"); 
     if(!isInDB(conn, archiveID, DIVA)){ 
      stmt.setString(1,archiveID); 
      stmt.setString(2,DIVA); 
      stmt.setString(3,docName); 
      stmt.addBatch(); 
     } 

    }catch (IndexOutOfBoundsException ex){ 
     endOfDoc = true; 
    } 

    //dump to database every batchSize 
    if(++count % batchSize == 0) { 
     //System.out.println("executing batch"); 
     stmt.executeBatch(); 
     conn.commit(); 
     count=0; 
    } 
} 

下面是实际的查询方法:

//returns false if combo is not in All Records, returns true if there 
public static boolean isInDB(Connection conn, String archiveID, String DIVA) throws SQLException { 
    Connection c = conn; 
    Statement stmt = null; 
    try { 
     Class.forName("org.sqlite.JDBC"); 

     stmt = c.createStatement(); 
     ResultSet rs = stmt.executeQuery("SELECT * FROM AllRecords WHERE ArchiveID=\"" + archiveID +"\" AND DivaCat=\""+DIVA +"\""); 
     if (rs.next()) { 
     return true; 
     }else{ 
      System.out.println(archiveID+DIVA+" is not in DB"); 
      rs.close(); 
      stmt.close(); 
      return false; 

     } 
    } catch (Exception e) { 
     System.err.println(e.getClass().getName() + ": " + e.getMessage()); 
     System.exit(0); 
    } 
    return false; 

} 

谢谢!

+2

那么,有什么问题吗? – VHS

+0

重用'stmt'。你有索引吗? –

+0

@VHS对于超过100,000个单独查询,查询速度太慢。我如何加快速度? –

回答

0

没有任何索引,查找所需的行需要数据库遍历整个表,以便执行每个查询。

您可以通过索引功能查找列优化这个特定的查询查找:

CREATE INDEX whatever ON AllRecords(ArchiveID, DivaCat); 
+1

谢谢!大幅度提速。 –

0

您的isInDB方法每次都连接到数据库。你不需要它。你也可以只用一个查询来完成。

sqlQuery = "SELECT * FROM AllRecords WHERE " 

for(int i =0;i < batchSize;i++){ 
    ... 
    if(i ==0) 
     sqlQuery + = "ArchiveID=\"" + archiveID +"\" AND DivaCat=\""+DIVA +"\""; 
    else 
     sqlQuery + = " OR ArchiveID=\"" + archiveID +"\" AND DivaCat=\""+DIVA +"\""; 

之后执行sqlQuery查询并检查你的每行与rs结果。

+2

可能应该使用一个StringBuilder这个 –