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



## student86 (11. Jun 2015)

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:


```
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


----------



## VfL_Freak (11. Jun 2015)

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


----------



## stg (11. Jun 2015)

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.


----------



## MisterBu (11. Jun 2015)

Um was für ein DBMS (Database Management System) handelt es sich denn?


----------



## Tom299 (11. Jun 2015)

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


----------



## student86 (12. Jun 2015)

Vielen dank für die antworten:

```
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.


----------



## Tom299 (12. Jun 2015)

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?


----------



## stg (12. Jun 2015)

student86 hat gesagt.:


> Vielen dank für die antworten:
> 
> ```
> String line;
> ...



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!


----------



## student86 (12. Jun 2015)

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.


----------



## Tom299 (12. Jun 2015)

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.


----------



## stg (12. Jun 2015)

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.


----------



## student86 (12. Jun 2015)

Vielen Dank !!


----------

