我有一个java程序,我在循环内的SQLite数据库上执行数千个查询。如果查询显示为空,则插入该行。如果查询有结果,我会忽略。我通常以1000个批量执行这些单独的查询,但最终将有数十万个查询来完成此任务。
因为我有数千行我正在检查个别查询,所以该程序的这部分运行速度非常慢。
是否有更有效的方法来执行这么多查询?
这是一个循环,它不断从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;
}
谢谢!
答案 0 :(得分: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结果检查每一行。
答案 1 :(得分:0)
没有任何索引,找到所需的行需要数据库遍历整个表,以执行每个查询。
您可以通过索引两个查找列来优化此特定查询中的查找:
CREATE INDEX whatever ON AllRecords(ArchiveID, DivaCat);