Performance enorm langsam

Status
Nicht offen für weitere Antworten.

MalakEkan

Mitglied
Also es geht um folgendes. Ich habe eine Textdatei die ich zeile für zeile auslese. Je nachdem welche Wörter am Anfang einer Zeile steht soll mein Programm mir diese Zeile in eine Datenbank schreiben. Also wenn die Zeile mit xyz anfängt so soll er mir diese komplette Zeile in die Datenbank schreiben.
Ich habe es bis jetzt so gelöst


Code:
BufferedReader datei= new BufferedReader(new FileReader("[b]PFAD ZUR DATEI[/b]"));
		String sZeile, query;
		sZeile=datei.readLine();



		/** Daten von der Textdatei einlesen und bearbeiten */
		while(sZeile != null){
			if (sZeile.startsWith("dn: ")){

				query="INSERT INTO Temp(dn) VALUES ('"+ sZeile.substring(4) + "');";
				stmt.executeUpdate(query);
				ID = sZeile.substring(4);
			}
			else 
				if (sZeile.startsWith("displayName:")){
					query="UPDATE Temp SET displayname = '" + sZeile.substring(12) + "' WHERE dn = '" + ID + "';";
					stmt.executeUpdate(query);
				}
				else
					if(sZeile.startsWith("objectClass:")){

						if((sZeile.startsWith("user", 13)) || sZeile.startsWith("computer", 13)){
							query="UPDATE Temp SET typ = '" + sZeile.substring(12) + "' WHERE dn = '" + ID + "';";
							stmt.executeUpdate(query);
						}
						
					}
			sZeile=datei.readLine();
		}

Das ganze klappt soweit wirklich gut. Nur dauert es enorm lange bis die Daten eingelesen wurden.
Vielleicht sollte ich noch erwähnen das die Textdatei, die ich auslese so an die 8,3 MB groß ist. Wäre für jede Idee dankbar.
 
S

SlaterB

Gast
nun, wie soll man tausende Updates schneller machen?
die dürften sicherlich so lange dauern,
es sei denn du hast irgendwelche anderen Update-Mengen zum Zeitvergleich?

miss doch mal die Durchschnittszeit pro Update,
wirds sie vielleicht im Verlauf der Datei immer höher?

--------

falls mehrmals die gleichen Zeilen in der DB geändert werden,
dann ist es natürlich keine Frage, dass es sparsamer wäre, erst in Java den endgültigen Wert zu bestimmen und diesen dann einmalig zu speichern
 

EgonOlsen

Bekanntes Mitglied
Kannst es mal mit PreparedStatement versuchen. Also die PreparedStatements vor der Schleife generieren und in der Schleife nur noch füllen und ausführen. Je nach Datenbank bringt das durchaus was.
 
G

Guest

Gast
...und zusätzlich noch statt executeUpdate() in der Schleife nur addBatch()
und nach dem Verlassen der Schleife executeBatch(). Sind es zu viele Daten,
dann z.B. alle 1000 Records ein executeBatch() ausführen.
 

DP

Top Contributor
und nimm einen stringbuffer.append anstatt das ewige stirng + " " + string etc., das frisst performance ohne ende
 

bronks

Top Contributor
DP hat gesagt.:
und nimm einen stringbuffer.append anstatt das ewige stirng + " " + string etc., das frisst performance ohne ende
Das glaube ich nicht und würde es gerne bewiesen haben. O.g. Code läßt sich durch die Verwendung eines Stringbuffers sicher nicht schneller machen. Das + dürfte für diesen Einsatzzweck das einzige wahre sein.
 

Caffè Latte

Bekanntes Mitglied
Hi,

bronks hat gesagt.:
DP hat gesagt.:
und nimm einen stringbuffer.append anstatt das ewige stirng + " " + string etc., das frisst performance ohne ende
Das glaube ich nicht und würde es gerne bewiesen haben. O.g. Code läßt sich durch die Verwendung eines Stringbuffers sicher nicht schneller machen. Das + dürfte für diesen Einsatzzweck das einzige wahre sein.

Der Beweis ist schon tausendmal erbracht worden. Da Strings immutable sind, wird bei jeder Konkatenation ein neues Stringobjekt erzeugt, dies ist extrem inperformant.

Im obigen Fall würde ich trotzdem zu PreparedStatements raten ...
 

bronks

Top Contributor
Caffè Latte hat gesagt.:
... Der Beweis ist schon tausendmal erbracht worden. Da Strings immutable sind, wird bei jeder Konkatenation ein neues Stringobjekt erzeugt, dies ist extrem inperformant ...
Weil es DP gerade hier erwähnt hat, habe ich ein vergleichbares Beispiel zu o.g. durch den Profiler gejagt.

Den Stringbuffer müsste man m.E. in o.g. Beispiel für jeden Satz leeren oder ein neues StringBufferObjekt erstellen. Gibt es sonst eine andere Möglichkeit einen kompletten SQL-String zusamenzubasteln?

@MalakEkan:
Wenn Du das PreparedStatement getestet hast, dann berichte bitte, ob es Vorteile gebracht hat.
 

DP

Top Contributor
ich habe es mehr generell gemeint. in einer schleife ist ein pstmt sicherlich performanter.
 

robertpic71

Bekanntes Mitglied
Neben der Verwendung von PreparedStatements noch andere Anregungen:

Wie schaut es mit dem Commit aus? Ist Autocommit eingeschaltet? Sowohl Autocommit ein (je DB-Update noch ein 2. für das Commit), als auch Autocommit aus (große Transaktionen werden von der DB zwischengespeichert/gesperrt) wirken sich negativ auf die Performance aus.

Meine Empfehlung:
Autocommit aus. COMMIT nach allen 500 Updates (ev. andere Werte testen, hier können je nach Datenmenge/Datenbank, andere Werte performanter sein) und ein COMMIT am Ende!

Das gleiche gilt hier auch für das Batch-Update. Ein riesiges Batch-Update macht eher Probleme (Bufferüberlauf) als mehere Updategruppen mit jeweils (z.B. 500 oder 1000) Statements.

Das Batch-Update würde ich erst machen, wenn das andere (PreparedStatement + Commit-Gruppen) nicht genung bringt.
 
S

SlaterB

Gast
bronks hat gesagt.:
Den Stringbuffer müsste man m.E. in o.g. Beispiel für jeden Satz leeren oder ein neues StringBufferObjekt erstellen. Gibt es sonst eine andere Möglichkeit einen kompletten SQL-String zusamenzubasteln?
leeren wäre gut (aber vorher testen ob nicht langsamer als neu erstellen ;) ),

neu erstellen ist aber auch nicht schlimm
wann immer zwei Strings mit + verbunden werden, wird intern eh ein StringBuffer erstellt,
durch manuelles Nachbauen wird das nicht langsamer,

aber schon ab drei Strings und zwei + ist dieser eine StringBuffer besser als die zwei, die intern erstellt werden würden
 

bronks

Top Contributor
SlaterB hat gesagt.:
...
leeren wäre gut (aber vorher testen ob nicht langsamer als neu erstellen ;) ),

neu erstellen ist aber auch nicht schlimm
wann immer zwei Strings mit + verbunden werden, wird intern eh ein StringBuffer erstellt,
durch manuelles Nachbauen wird das nicht langsamer,

aber schon ab drei Strings und zwei + ist dieser eine StringBuffer besser als die zwei, die intern erstellt werden würden
Du irrst Dich!
Code:
public class ZeitmessungBufferAppend {
    
    String s;
    StringBuffer sb = new StringBuffer();
    String s1 = "jklö";
    int it = 1000000;
    /** Creates a new instance of ZeitmessungBufferAppend */
    public ZeitmessungBufferAppend() {
        System.out.println("X");
        
        long m1 = System.currentTimeMillis();
        for(int i=0; i<it; i++){
            sb.delete(0, sb.length());
            sb.append("asdf" + i + "fdsa" + s1 + "noch etwas" + s1 + i +  "X" + "x");
        }
        
        
        long m2 = System.currentTimeMillis();
        for(int i=0; i<it; i++){
            sb = new StringBuffer();
            sb.append("asdf" + i + "fdsa" + s1 + "noch etwas" + s1 + i + "X" + "x");
        }
        
        long m3 = System.currentTimeMillis();

        for(int i=0; i<it; i++){
            s=null;
            s=("asdf" + i + "fdsa" + s1 + "noch etwas" + s1 + i + "X" + "x");
        }
        
        long m4 = System.currentTimeMillis();
        System.out.println(m2-m1);
        System.out.println(m3-m2);
        System.out.println(m4-m3);
    }

    public static void main(String[] args){
        ZeitmessungBufferAppend test = new ZeitmessungBufferAppend();
    }
}
 

Murray

Top Contributor
@bronks: Einen StringBuffer zu erzeugen, um ihn dann nicht zu verwenden, ist aber sicher nicht Sinn der Sache.

Und in solchen Situationen, in denen Thread-Synchronisierung nicht benötigt wird, sollte man ohnehin lieber den
StringBuilder verwenden (ab JDK 1.5)
 

The_S

Top Contributor
@bronks

1. siehe Murray
2. siehe DP
3. es sagen dir so viele Leute die Ahnung von der Materie haben, warum glaubst dus nicht einfach?
 

Wildcard

Top Contributor
Ist zwar schon oft genug gesagt worden, aber ich schließe mich gerne an das
Code:
sb.append("asdf" + i + "fdsa" + s1 + "noch etwas" + s1 + i + "X" + "x");
völlig daneben ist :lol:
Wo wir aber dabei sind:
Solange keine synchronisierung erforderlich ist sollte man den StringBuilder statt dem Buffer nehmen und in beiden Fällen ist es sehr wichtig eine sinnvolle initiale Kapazität festzulegen (wann immer möglich).
 

bronks

Top Contributor
Murray hat gesagt.:
@bronks: Einen StringBuffer zu erzeugen, um ihn dann nicht zu verwenden, ist aber sicher nicht Sinn der Sache ...
OK OK ... ...!

Ab morgen schütte ich mir keinen Eierlikör mehr in den Frühstückskaffee. :oops:

Nach dem der Rausch ausgeschlafen ist sieht die Welt gleich ganz anders aus:
Code:
public class ZeitmessungBufferAppend {
    
    String s;
    StringBuffer sb = new StringBuffer();
    String s1 = "jklö";
    int it = 1000000;
    /** Creates a new instance of ZeitmessungBufferAppend */
    public ZeitmessungBufferAppend() {
        System.out.println("X");
        
        long m1 = System.currentTimeMillis();
        for(int i=0; i<it; i++){
            sb.delete(0, sb.length());
            sb.append("asdf");
            sb.append(i);
            sb.append("fdsa");
            sb.append(s1);
            sb.append("noch etwas");
            sb.append(s1);
            sb.append(i);
            sb.append("X");
            sb.append("x");
        }
        
        
        long m2 = System.currentTimeMillis();
        for(int i=0; i<it; i++){
            sb = new StringBuffer();
            sb.delete(0, sb.length());
            sb.append("asdf");
            sb.append(i);
            sb.append("fdsa");
            sb.append(s1);
            sb.append("noch etwas");
            sb.append(s1);
            sb.append(i);
            sb.append("X");
            sb.append("x");
        }
        
        long m3 = System.currentTimeMillis();

        for(int i=0; i<it; i++){
            s=null;
            s=("asdf" + i + "fdsa" + s1 + "noch etwas" + s1 + i + "X" + "x");
        }
        
        long m4 = System.currentTimeMillis();
        System.out.println(m2-m1);
        System.out.println(m3-m2);
        System.out.println(m4-m3);
    }

    public static void main(String[] args){
        ZeitmessungBufferAppend test = new ZeitmessungBufferAppend();
    }
}
 

MalakEkan

Mitglied
Also ich wollte es jetzt mit dem PreparedStatement versuchen. Allerdings bekomme ich jetzt immer einen NullPoitnerException.
HIer der Code:

Code:
BufferedReader datei= new BufferedReader(new FileReader(PFAD ZUR DATEI));
		
	      String sZeile; 
	      sZeile=datei.readLine(); 

	      
	      PreparedStatement psInsert=con.prepareStatement("INSERT INTO Temp(dn, displayname, typ) VALUES ('?', '?', '?');");
	      /** Daten von der Textdatei einlesen und bearbeiten */ 
	      while(sZeile != null){ 
	         if (sZeile.startsWith("dn: ")){ 

	            
	        	 String string=sZeile.substring(4);
	        	 psInsert.setString(1, string);
	        	  
	         } 
	         else 
	            if (sZeile.startsWith("displayName:")){ 
	                
	                 psInsert.setString(2, sZeile.substring(12));
	            } 
	            else 
	               if(sZeile.startsWith("objectClass:")){ 

	                  if((sZeile.startsWith("user", 13)) || sZeile.startsWith("computer", 13)){ 
	                     	  psInsert.setString(3, sZeile.substring(12));
	                	  psInsert.executeUpdate();
	                  } 
	                   
	               } 
	         sZeile=datei.readLine(); 
	      }

Laut Eclipse ist der Fehler (in diesem Codeabschnitt) in Zeile 14. Aber das ist mir unbegreiflich. Der String ist richtig und die Syntax vom PreparedStatement auch. Also wo ist da der Fehler?
 
S

SlaterB

Gast
was soll dieser Quatsch-Code?
schreibe
Code:
PreparedStatement psInsert=con.prepareStatement(
   "INSERT INTO Temp(dn, displayname, typ) VALUES ('?', '?', '?');");
psInsert.setString(1, "test");

entweder das geht oder nicht,
wenn es nicht geht dann darfst du dich weiter wundern,

wenn doch, dann ist alles klar und es ist ein Fehler in deinem Code, der nur noch gefunden werden muss

der nächste Test wäre z.B.
Code:
PreparedStatement psInsert=con.prepareStatement(
  "INSERT INTO Temp(dn, displayname, typ) VALUES ('?', '?', '?');");
         while(sZeile != null){
            if (sZeile.startsWith("dn: ")){

               psInsert.setString(1, "test");
               
            }
            sZeile=datei.readLine();
         }

geht das, ja oder nein?

und so gehts Schritt für Schritt voran,
ein Fehler im fertigen Programm NICHT zu finden ist keine Kunst..


------------

und probiere mal
"VALUES (?, ?, ?);"
statt
"VALUES ('?', '?', '?');"
 

DP

Top Contributor
und wenn dann

Code:
INSERT INTO Temp(dn, displayname, typ) VALUES (?, ?, ?);");
 

MalakEkan

Mitglied
Danke habs gemerkt. Aber die Performance ist immer noch so lahm. So wirklich was nutzen tut das PreparedStatement auch nichts :?
 

robertpic71

Bekanntes Mitglied
1.) Gibt es jetzt noch die Updatebefehle oder nur noch das Insert?

2.) Hast du einen Index (oder mehrere CREATE INDEX...) über Datei liegen?

3.) Autocommit?

Teste mal:

Vor der Schleife:
con.setAutoCommit(false);
int sqlCounter = 0;

In der SChleife beim Update:
Code:
if (sqlCounter++ > 300) {
    con.commit();
    sqlCounter = 0;
}

nach der Schleife:
Code:
if (sqlCounter++ > 0) {
    con.commit();
}

Eventuell liegt das Problem auch an der Ewartungshaltung? Welche Datenmengen kommen da in die Datenbank (Sätze/Größe)?

Die nächste Steigerung wäre ein Batch-Update.

Statt

psInsert.executeUpdate();

kommt

psInsert.addBatch();


Und in die 2 If's von oben kommt vor das Commit (Beispiel ohne Statusabfrage):
psInsert.executeBatch();
 

MalakEkan

Mitglied
Danke für eure Hilfe.
Die Perfomance ist viel besser als zum Anfang.

Jetzt braucht das Programm nur noch 5 Sekunden für 215968 Textzeilen zum einlesen.

Ich denke das ist eine akzeptable Zeit oder?
 
S

SlaterB

Gast
interessant wäre da die vorherige Zeit und welche Verfahren letztlich etwas beigetragen haben
(falls das nicht schon irgendwo steht, habe nicht alles gelesen)
 

MalakEkan

Mitglied
Die Zeit habe ich leider nicht von Anfang an gemessen.
Ich kann nur soviel sagen das es am Anfang solange gedauert hat das man sich in aller Ruhe einen Kaffee hätte holen können.

Ich vermute mal es hat einiges gebracht das ich diese Updates nicht mehr jedesmal durchführe.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
8u3631984 Frage Performance bei Linked List und Array List Allgemeine Java-Themen 5
H Performance einer Monte-Carlo-Simulation verbessern Allgemeine Java-Themen 6
goldmensch Datentypen Welche Methode hat die bessere Performance? Allgemeine Java-Themen 12
H Watson-Crick-Complement Performance Allgemeine Java-Themen 18
L Best Practice Auslagerung von Code = Performance Optimierung? Allgemeine Java-Themen 4
B Performance Messungen Allgemeine Java-Themen 4
J Threads verbessern die Performance NICHT ? Allgemeine Java-Themen 8
X Performance für Tomcat / Apache optimieren Allgemeine Java-Themen 2
I Performance - JDBC UPC PoolDataSoure Allgemeine Java-Themen 0
E Lambda filter performance Allgemeine Java-Themen 2
D Performance-Probleme mit Joda-Time Allgemeine Java-Themen 3
A Jasper Report Performance bei PDF erzeugen Allgemeine Java-Themen 0
A Best Practice Variablen vertauschen - Performance Allgemeine Java-Themen 1
R DBUnit Performance Probleme Allgemeine Java-Themen 0
P Performance: super explizit erwähnen oder weglassen? Allgemeine Java-Themen 5
S starke performance probleme des forums Allgemeine Java-Themen 10
C Performance Tips Allgemeine Java-Themen 13
A Performance/Speicherplatz-Nutzung bei Tests Allgemeine Java-Themen 6
R Java Performance testen Allgemeine Java-Themen 18
StrikeTom Java Performance Fragen Allgemeine Java-Themen 5
V Performance steigern Allgemeine Java-Themen 7
D Reflection-Performance Allgemeine Java-Themen 7
M Einfluss von Caching auf die Performance (große Arrays) Allgemeine Java-Themen 24
R Collections Performance einer HashMap Allgemeine Java-Themen 26
i<3java [Groovy/Grails](oder auch java) Mögliche Performance Probleme bei Mailversendung Allgemeine Java-Themen 2
D Performance Objektallokation Allgemeine Java-Themen 28
J Java Performance nicht nachvollziehbar Allgemeine Java-Themen 3
I Library für High Performance Mime Type Erkennung Allgemeine Java-Themen 8
S Performance Frage: Objekt oder static? Allgemeine Java-Themen 33
M Runtime.exec() - Performance / Frage zu Threads Allgemeine Java-Themen 5
M Performance Allgemeine Java-Themen 6
M Performance Allgemeine Java-Themen 5
E Performance website download Allgemeine Java-Themen 13
MQue Performance Methodenaufruf - if Abfrage Allgemeine Java-Themen 19
hdi Was frisst in meinem Programm den Speicher / verschlechtert die Performance Allgemeine Java-Themen 11
J Performance von Java GUI-Anwendungen Allgemeine Java-Themen 2
U Java Performance im Vergleich zu C++ in speziellem Anwendungsfall Allgemeine Java-Themen 6
S Performance und Function Call Depth Allgemeine Java-Themen 6
H Performance Vorteil durch Wechsel der JVM? Allgemeine Java-Themen 6
A Performance: byte[] in byte[][][] konvertieren Allgemeine Java-Themen 2
T Performance ArrayList#remove Allgemeine Java-Themen 8
ARadauer Performance Pptimierung -Lesen/Schreiben Allgemeine Java-Themen 10
Chris81T Performance Problem durch mehrfaches Starten eines JAVA Prog Allgemeine Java-Themen 8
G Hibernate, JTable und Performance Allgemeine Java-Themen 17
M Listener und Performance Allgemeine Java-Themen 9
P Performance: Ziehen ohne Zurücklegen (große Datenmenge) Allgemeine Java-Themen 10
D Performance: ArrayList vs. Array vs. "Eigene Liste&quot Allgemeine Java-Themen 8
M nichtreferenzierte Objekte auf NULL setzen -> Performance Allgemeine Java-Themen 4
S Ursache für schlechte Performance Allgemeine Java-Themen 2
L Java Performance Check Tool Allgemeine Java-Themen 3
S Performance von Comparator Allgemeine Java-Themen 3
egrath Performance Problem mit File-I/O Allgemeine Java-Themen 6
S Performance Problem Allgemeine Java-Themen 11
X Java Performance auf Sun Systemen bzw. generell Allgemeine Java-Themen 4
T Performance String-Operationen und StringBuffer (1.4und 1.5) Allgemeine Java-Themen 18
P miese performance bei nem BufferedImage + repaint :( Allgemeine Java-Themen 6
T Performance-Grundlagen Allgemeine Java-Themen 4
G Performance Problem bei der Übertragung Server zum Client Allgemeine Java-Themen 3
V Performance Leck finden Allgemeine Java-Themen 3
T Tile Game Performance Allgemeine Java-Themen 32
F Performance von Reflection vs Statisches Coden Allgemeine Java-Themen 4
M Performance: Java zu C/C++ bei Datenbankanwendung Allgemeine Java-Themen 3
Y unnecessary cast & Performance Allgemeine Java-Themen 29
conan2 Performance von paint() Allgemeine Java-Themen 2
G Performance JDOM - DOM - eigene HashMap (SAX) Allgemeine Java-Themen 2
F Bilder als "Thumbnails" laden - Performance Allgemeine Java-Themen 6
S Java3D Performance optimieren Allgemeine Java-Themen 5
F Wenn ihr Performance wollt nehmt C++ Allgemeine Java-Themen 39
N Performance-Test (Geschwindigkeit von Methoden vergleichen)? Allgemeine Java-Themen 4
S Performance Test mit JMeter Allgemeine Java-Themen 2
T Performance Allgemeine Java-Themen 8
J Anfängerliste für gute Performance? Allgemeine Java-Themen 3
Luma Performance-Problem mit RandomAcces File Allgemeine Java-Themen 4
I Performance bei "String <-> Byte"-Umwandlung Allgemeine Java-Themen 4
I Performance-Probleme bei Schleife Allgemeine Java-Themen 3
C Performance von FOR Schleifen Allgemeine Java-Themen 25
C Performance Vergleich, Java vs. Tcl/Tk Allgemeine Java-Themen 3
C Speicherverbrauch von JDialog enorm Allgemeine Java-Themen 6
R JDK installieren OpenJDK-Aufruf sehr langsam Allgemeine Java-Themen 4
K Arbeitsspeicher wird langsam voll Allgemeine Java-Themen 6
E JavaFX RMI extrem langsam wenn Server nicht läuft Allgemeine Java-Themen 5
Thallius String erzeugen sehr langsam Allgemeine Java-Themen 16
S JNLP startet seit 1.8.0_31 sehr langsam + Windows-Systemverzeichnis Allgemeine Java-Themen 3
P Eclipse langsam/unbrauchbar bei größeren Quelldateien? Allgemeine Java-Themen 8
W Threads NullPointer: Konstruktor "zu langsam"? Allgemeine Java-Themen 3
M Externe Jar sehr langsam Allgemeine Java-Themen 23
C JEditorPane langsam großes HTML Allgemeine Java-Themen 8
J Laden von JAR Files geht ohne ADMIN Rechte sehr langsam Allgemeine Java-Themen 6
H Kopieren sehr langsam Allgemeine Java-Themen 5
B Cipher.getInstance Aufruf sehr langsam Allgemeine Java-Themen 2
B util.Timer zu langsam? Allgemeine Java-Themen 3
W Java Applet läuft langsam Allgemeine Java-Themen 2
N Liste mit Map abgleichen extrem langsam Allgemeine Java-Themen 6
C Darstellung der Liste bei vielen Daten extrem langsam Allgemeine Java-Themen 11
B JavaPanels langsam schliessen und öffne Allgemeine Java-Themen 6
L Java Debugmodus ist unerträglich langsam! Allgemeine Java-Themen 30
L Java 1.5 - Anwendung unter 1.6 JRE sehr langsam geworden Allgemeine Java-Themen 8
H JID3 + vdheide schreiben zu langsam Allgemeine Java-Themen 11
M String zusammensetzen->sehr langsam Allgemeine Java-Themen 3
T ObjectOutputStream#writeObject() zu langsam. Allgemeine Java-Themen 13

Ähnliche Java Themen

Neue Themen


Oben