2016-11-30 2 views
1

Ich habe ein Java-Programm, in dem ich Tausende von Abfragen in einer SQLite-Datenbank innerhalb einer Schleife durchführe. Wenn die Abfrage leer angezeigt wird, füge ich die Zeile ein. Wenn die Abfrage ein Ergebnis hat, ignoriere ich. Ich führe diese einzelnen Abfragen im Allgemeinen in 1000er-Stapeln durch, aber am Ende werden einige Hunderttausende von Abfragen insgesamt vorhanden sein, um diese Aufgabe zu erledigen.Java sqlite führt Tausende von Abfragen aus

Da ich Tausende von Zeilen habe, die ich mit einzelnen Abfragen überprüfe, läuft dieser Teil des Programms sehr langsam.

Gibt es eine effizientere Möglichkeit, diese vielen Abfragen auszuführen?

ist die Schleife, die die ursprünglichen Daten aus Excel-Dokumente, bis alle zieht ständig die Information gelesen wird:

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; 
    } 
} 

Hier ist die Methode eigentliche Abfrage ist:

//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; 

} 

Dank!

+2

Also, was ist die Frage? – VHS

+0

Wiederverwendung 'stmt'. Haben Sie Indizes? –

+0

@ VHS Die Abfragen sind für weit über 100.000 einzelne Abfragen zu langsam. Wie kann ich das beschleunigen? –

Antwort

0

Ohne einen Index erfordert das Suchen der gewünschten Zeile (n), dass die Datenbank für jede Abfrage die gesamte Tabelle durchläuft.

Sie können durch die Indizierung beide Nachschlagespalten den Nachschlag in dieser speziellen Abfrage optimieren:

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

Danke! MASSIVE Geschwindigkeitssteigerung. –

0

Ihre isInDB-Methode verbindet sich jedes Mal mit der Datenbank. Du brauchst es nicht. Das können Sie auch mit nur einer Abfrage tun.

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 +"\""; 

Danach führen Sie sqlQuery Abfrage und überprüfen Sie jede Zeile mit rs Ergebnisse.

+2

Wahrscheinlich sollte dafür ein StringBuilder verwendet werden. –

Verwandte Themen