CSV Datein in DB übernehmen:PreparedStatement bzw executeBatch() zu langsam

student86

Mitglied
Moin Moin,
Möchte eigentlich ganz easy den inhalt der csv datei in die DB schreiben. Sind ein paar tausend Lines.
Ich hab gelesen das 100 lines mit der methode 0,7 sek. dauern. Bei mir dauert der vorgang aber über 20 minuten ....

Java Code:

Code:
        String line;	
        String[]values;
        PreparedStatement st = connection.prepareStatement("INSERT INTO Symboltabelle VALUES (?, ?);");
        while ((line=bufferreader.readLine())!=null){
        values=line.split(";");
        st.setString(1, values[0]);
        st.setString(2, values[1])
        st.addBatch();
        }
        st.executeBatch();

jemand eine Idee wieso es so langsam ist ?

Genauer : das ps.executeBatch() brauch die 20 min ^^
MFG
 
Zuletzt bearbeitet:
Moin,

mal so auf die Schnelle und ins Blaue geraten:

addBatch(): Adds a set of parameters to this PreparedStatement object's batch of commands.

Das bedeutet, das Du zuerst alle (also alle 'paar Tausend') Zeilen liest, splittest und das jeweilige CMD ins Batch des Objekts st schreibst ... das KANN so nicht performat sein !!

Gruß Klaus
 
Ach das bisschen Spielerei mit den String sollte nicht sooo wild sein (das dauert jedenfalls sicherlich keine 20min! 🙂 )

Ich tippe vielmehr darauf, dass hier falsch mit Transaktionen umgegangen wird und jede Statement einzeln comitted wird ... ist zwar anhand des Codes hier nicht wirklich ersichtlich, aber anders kann ich mir die lange Laufzeit nicht erklären.
 
ich hab die gleiche vermutung wie stg:
probier mal autocommit auf false setzen, dann die inserts machen und danach 1x commit.

ps: addBatch hab ich noch nie verwendet
 
Vielen dank für die antworten:
Java:
        String line;	
        String[]values;
        connection.setAutoCommit(false);
        PreparedStatement st = connection.prepareStatement("INSERT INTO Symboltabelle VALUES (?, ?);");
        while ((line=bufferreader.readLine())!=null){
        values=line.split(";");
        st.setString(1, values[0]);
        st.setString(2, values[1])
        st.addBatch();
        }
connection.commit();
        st.executeBatch();

also er läuft nun direkt durch , aber die DB bleibt leer.
das mit dem einmaligen commit versteh ich nicht, das kommmt mir so falsch vor.
 
Laß mal die 2 Batch-Aufrufe weg und benutz st.executeUpdate() und danach kommt der commit.

Ist ein Batch nicht dafür da, etwas zu einem späteren Zeitpunkt auszuführen?
 
Zuletzt bearbeitet:
Vielen dank für die antworten:
Java:
        String line;	
        String[]values;
        connection.setAutoCommit(false);
        PreparedStatement st = connection.prepareStatement("INSERT INTO Symboltabelle VALUES (?, ?);");
        while ((line=bufferreader.readLine())!=null){
        values=line.split(";");
        st.setString(1, values[0]);
        st.setString(2, values[1])
        st.addBatch();
        }
connection.commit();
        st.executeBatch();

also er läuft nun direkt durch , aber die DB bleibt leer.
das mit dem einmaligen commit versteh ich nicht, das kommmt mir so falsch vor.

Der commit ist zu früh. Du musst natürlich comitten, nachdem du die statements mit st.executeBatch(); ausgeführt hast. Vertausch also einfach mal diese beiden Zeilen!
 
Ja so geht das 🙂

aber verstanden hab ich das nicht.
durch das execute Batch schreibe ich doch die daten aus dem Statment in die Datenbank.
passt das commit() die Daten nachträglich an?
bzw was genau macht ein commit()?
das klärt nicht meine Fragezeichen🙂
Makes all changes made since the previous commit/rollback permanent and releases any database locks currently held by this Connection object. This method should be used only when auto-commit mode has been disabled.
 
Wie das intern genau funktioniert, weiß ich nicht, aber ich vermute mal, die Daten werden zuerst in den Puffer/Zwischenspeicher der Datenbank geschrieben und erst beim Commit auf die Festplatte. Mit einem Rollback anstatt einem Commit macht man die Änderungen wieder rückgängig.

Deswegen sieht man dann normalerweilse das Commit im try {} Block und das Rollback mit catch{} Block.
 
Zuletzt bearbeitet:
Du kannst dir das in etwa so verstellen:
Zunächst werden der Datenbank nur die auszuführenden Befehle mitgeteilt. Erst mit dem Commit werden die Befehle dann tatsächlich physisch ausgeführt und damit in deinem Fall die Daten in die Datenbank geschrieben.
 

Zurück
Oben