Autor |
Beitrag |
D. Annies
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Di 07.07.09 20:13
Hi, Delpher,
warum ist der folgende Code, durch den eine Merge-Datei entsteht, so langsam - ca. 2 sec pro Datensatz??
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143:
| procedure TForm1.Button28Click(Sender: TObject); var InputString : string; begin InputString := 'merge.dbf'; Inputstring := InputBox('Merge-Filename', 'Dateiname:', Inputstring); with form2.table1 do begin Active := False; TableName := Inputstring; TableType := ttDefault; FieldDefs.Clear; FieldDefs.Add('Name', ftString, 25, False); FieldDefs.Add('Vorname', ftString, 25, False); FieldDefs.Add('Klasse', ftString, 5, False); FieldDefs.Add('Geschlecht', ftString, 1, False); FieldDefs.Add('Gebdat', ftString, 10, False); FieldDefs.Add('Punkte', ftinteger); CreateTable; end; form2.table1.active := true;
table1.Close; table1.TableName := concat(home, '\', 'R1x.dbf'); table1.active := true; table1.First; while not table1.Eof do begin form2.Table1.Append; form2.Table1.fieldbyname('NAME').asstring := table1.fieldbyname('NAME').asstring; form2.Table1.fieldbyname('VORNAME').asstring := table1.fieldbyname('VORNAME').asstring; form2.Table1.fieldbyname('KLASSE').asstring := table1.fieldbyname('KLASSE').asstring; form2.Table1.fieldbyname('GESCHLECHT').asstring := table1.fieldbyname('Geschlecht').asstring; form2.Table1.fieldbyname('GEBDAT').asstring := table1.fieldbyname('gebdat').asstring; form2.Table1.fieldbyname('PUNKTE').asinteger := table1.fieldbyname('Punkte').asinteger; form2.table1.Post; table1.Next; end; showmessage('merge '+ table1.TableName + ' ok'); table3.Close; table3.TableName := concat(home, '\', 'R7x.dbf'); table3.active := true; table3.First; while not table3.Eof do begin form2.Table1.Append; form2.Table1.fieldbyname('NAME').asstring := table3.fieldbyname('NAME').asstring; form2.Table1.fieldbyname('VORNAME').asstring := table3.fieldbyname('VORNAME').asstring; form2.Table1.fieldbyname('KLASSE').asstring := table3.fieldbyname('KLASSE').asstring; form2.Table1.fieldbyname('GESCHLECHT').asstring := table3.fieldbyname('Geschlecht').asstring; form2.Table1.fieldbyname('GEBDAT').asstring := table3.fieldbyname('gebdat').asstring; form2.Table1.fieldbyname('PUNKTE').asinteger := table3.fieldbyname('Punkte').asinteger; form2.table1.Post; table3.Next; end; showmessage('merge '+ table3.TableName + ' ok'); table4.Close; table4.TableName := concat(home, '\', 'R8x.dbf'); table4.active := true; table4.First; while not table4.Eof do begin form2.Table1.Append; form2.Table1.fieldbyname('NAME').asstring := table4.fieldbyname('NAME').asstring; form2.Table1.fieldbyname('VORNAME').asstring := table4.fieldbyname('VORNAME').asstring; form2.Table1.fieldbyname('KLASSE').asstring := table4.fieldbyname('KLASSE').asstring; form2.Table1.fieldbyname('GESCHLECHT').asstring := table4.fieldbyname('Geschlecht').asstring; form2.Table1.fieldbyname('GEBDAT').asstring := table4.fieldbyname('gebdat').asstring; form2.Table1.fieldbyname('PUNKTE').asinteger := table4.fieldbyname('Punkte').asinteger; form2.table1.Post; table4.Next; end; showmessage('merge '+ table4.TableName + ' ok'); table5.Close; table5.TableName := concat(home, '\', 'R9x.dbf'); table5.active := true; table5.First; while not table5.Eof do begin form2.Table1.Append; form2.Table1.fieldbyname('NAME').asstring := table5.fieldbyname('NAME').asstring; form2.Table1.fieldbyname('VORNAME').asstring := table5.fieldbyname('VORNAME').asstring; form2.Table1.fieldbyname('KLASSE').asstring := table5.fieldbyname('KLASSE').asstring; form2.Table1.fieldbyname('GESCHLECHT').asstring := table5.fieldbyname('Geschlecht').asstring; form2.Table1.fieldbyname('GEBDAT').asstring := table5.fieldbyname('gebdat').asstring; form2.Table1.fieldbyname('PUNKTE').asinteger := table5.fieldbyname('Punkte').asinteger; form2.table1.Post; table5.Next; end; showmessage('merge '+ table5.TableName + ' ok'); table6.Close; table6.TableName := concat(home, '\', 'R5x.dbf'); table6.active := true; table6.First; while not table6.Eof do begin form2.Table1.Append; form2.Table1.fieldbyname('NAME').asstring := table6.fieldbyname('NAME').asstring; form2.Table1.fieldbyname('VORNAME').asstring := table6.fieldbyname('VORNAME').asstring; form2.Table1.fieldbyname('KLASSE').asstring := table6.fieldbyname('KLASSE').asstring; form2.Table1.fieldbyname('GESCHLECHT').asstring := table6.fieldbyname('Geschlecht').asstring; form2.Table1.fieldbyname('GEBDAT').asstring := table6.fieldbyname('gebdat').asstring; form2.Table1.fieldbyname('PUNKTE').asinteger := table6.fieldbyname('Punkte').asinteger; form2.table1.Post; table6.Next; end; showmessage('merge '+ table6.TableName + ' ok'); table7.Close; table7.TableName := concat(home, '\', 'R6x.dbf'); table7.active := true; table7.First; while not table7.Eof do begin form2.Table1.Append; form2.Table1.fieldbyname('NAME').asstring := table7.fieldbyname('NAME').asstring; form2.Table1.fieldbyname('VORNAME').asstring := table7.fieldbyname('VORNAME').asstring; form2.Table1.fieldbyname('KLASSE').asstring := table7.fieldbyname('KLASSE').asstring; form2.Table1.fieldbyname('GESCHLECHT').asstring := table7.fieldbyname('Geschlecht').asstring; form2.Table1.fieldbyname('GEBDAT').asstring := table7.fieldbyname('gebdat').asstring; form2.Table1.fieldbyname('PUNKTE').asinteger := table7.fieldbyname('Punkte').asinteger; form2.table1.Post; table7.Next; end; showmessage('merge '+ table7.TableName + ' ok'); table8.Close; table8.TableName := concat(home, '\', 'RDx.dbf'); table8.active := true; table8.First; while not table8.Eof do begin form2.Table1.Append; form2.Table1.fieldbyname('NAME').asstring := table8.fieldbyname('NAME').asstring; form2.Table1.fieldbyname('VORNAME').asstring := table8.fieldbyname('VORNAME').asstring; form2.Table1.fieldbyname('KLASSE').asstring := table8.fieldbyname('KLASSE').asstring; form2.Table1.fieldbyname('GESCHLECHT').asstring := table8.fieldbyname('Geschlecht').asstring; form2.Table1.fieldbyname('GEBDAT').asstring := table8.fieldbyname('gebdat').asstring; form2.Table1.fieldbyname('PUNKTE').asinteger := table8.fieldbyname('Punkte').asinteger; form2.table1.Post; table8.Next; end; showmessage('merge '+ table8.TableName + ' ok'); label21.Caption := inputstring; showmessage('MergeFile wurde erzeugt'); end; |
Da bin ich mal gespannt auf eure Antworten,
Detlef
_________________ ut vires desint, tamen est laudanda voluntas
|
|
Niko S.
      
Beiträge: 566
Erhaltene Danke: 10
Win 7, Ubuntu
Lazarus, Turbo Delphi, Delphu 7 PE
|
Verfasst: Di 07.07.09 20:16
sind diese tables sichtbare objekte? wenn ja mach die mal unsichtbar meistens ist das denn viel schneller..
|
|
Regan
      
Beiträge: 2157
Erhaltene Danke: 72
Java (Eclipse), Python (Sublimetext 3)
|
Verfasst: Di 07.07.09 20:26
Kann es sein, dass das asstring sehr lange dauert? Ich habe zwar von dieser Datenbankart keine Ahnung, aber Strings umwandeln dauert ja an sich schon lange.
|
|
Sinspin
      
Beiträge: 1335
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Di 07.07.09 20:27
Niko S. hat folgendes geschrieben : | sind diese tables sichtbare objekte? wenn ja mach die mal unsichtbar meistens ist das denn viel schneller.. |
Joa, dem schließe ich mich an!
Man kann mit einem Aufruf Table.DisableControls dafür sorgen das eine Tabelle keine Ereignisse mehr von sich gibt wenn sich an ihr was ändert, also bei Datensatzwechsel oder so. Mit EnableControls musst du das dann aber wieder anschalten wenn du fertig bist.
Statt den Zweisungen via AsString kannst du es auch mal mit Value probieren. ( FieldByName('xxx').Value := FieldByName('xxx').Value) So müssten sich eigentlich ein paar Sekunden über die gesammten Daten rausschlagen lassen.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mi 08.07.09 09:32
Über wieviel Datensätze reden wir denn hier?
Offensichtlich setzt du auch noch die BDE ein. Mach mal zwischendurch ein FlushBuffers. Wenn ich mich richtig erinnere, wird sonst alles "irgendwo" zwischengespeichert, bis die Datenbank genug Zeit hat, dass wirklich zu speichern.
Es gibt noch weiteres Optimierungspotential:
- AsString rausschmeißen.
- Statt FieldByName über Fields[FeldIndex] zugreifen
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Mi 08.07.09 16:09
Danke für eure Ideen.
Aber da es nur ca. 900 DS waren, konnten diese Tuningmöglichkeiten nicht so viel bringen. Ich habe ganz "einfach" eine neue Table genommen, und dann ging's, also, in der obigen Lesart table3 statt table2.
Grüße aus Lübeck,
Detlef
_________________ ut vires desint, tamen est laudanda voluntas
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Do 09.07.09 00:58
Hey,
nur ma so nebenbei, warum hast dir nich ne extra Funktion gemacht, die die daten kopiert. Weil du machst ja 7ma das gleiche un wenn du was ändern musst, änderst du das dann 7ma. das is irgendwie umständlich...
Mfg Bergmann.
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Do 09.07.09 13:23
hast völlig recht, das mach ich als nächstes, eine schöne Proc mit Übergabeparameter.
Danke, Detlef
_________________ ut vires desint, tamen est laudanda voluntas
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Do 09.07.09 20:14
Übrigens: "FieldByName" sucht jedesmal das entsprechende Feld aus der Feldliste (mit einfacher For-Schleife).
Bei 900 Records ist das nicht so wild, aber grundsätzlich sollte man vor so einer Schleife seine Felder einmalig suchen und in einer lokalen 'TField'-Variablen speichern. Dann geht das nochmals schneller.
_________________ Na denn, dann. Bis dann, denn.
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Do 09.07.09 20:36
Hm, alzi, hast du mal ein Beispiel?
(vielleicht adaptiert von oben)
Detlef
_________________ ut vires desint, tamen est laudanda voluntas
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 10.07.09 08:23
D. Annies hat folgendes geschrieben : | Hm, alzi, hast du mal ein Beispiel? |
Klar, Deti
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| procedure TForm1.Button28Click(Sender: TObject); var InputString : string; fld1Name, fld1Vorname, fld1Klasse, fld1Geschlecht, fld1Datum, fld1Punkte, fld2Name, fld2Vorname, fld2Klasse, fld2Geschlecht, fld2Datum, fld2Punkte : TField;
begin ... table1.active := true; table1.First; fld1Name := form2.Table1.fieldbyname('NAME'); fld1Vorname := form2.Table1.fieldbyname('VORNAME'); ... fld2Name := Table2.fieldbyname('NAME'); fld2Vorname := Table2.fieldbyname('VORNAME'); ... while not table1.Eof do begin form2.Table1.Append; fld1Name.Value := fld2Name.Value; fld1Vorname.Value := fld2Vorname.Value; ... form2.table1.Post; table1.Next; end; showmessage('merge '+ table1.TableName + ' ok'); ... end; |
Oder gleich noch kompakter:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
| Function CreateStringListFromCommaString (aCommaText : String) : TStringList; Begin Result := TStringList.Create; Result.Delimiter := ','; Result.DelimitedText := aFieldNames; End;
Procedure CopyTables (aTblName : String; aSrc, aDst : TTable, aFieldnames : String); Var srcFields, dstFields : Array Of TField; i, fieldCount : Integer; slFieldNames : TStringList;
Begin aSrc.Close; aSrc.TableName := concat(home, '\', aTblName); aSrc.active := true; slFieldNames := CreateStringListFromCommaString(aFieldNames); Try setLength (srcFields, slFieldNames.Count); setLength (dstFields, slFieldNames.Count); fieldCount := Length (Fieldnames); For i := 0 to FieldCount - 1 do begin srcFields[i] := aSrc.FieldByname(slFieldnames[i]); dstFields[i] := aDst.FieldByname(slFieldnames[i]); End; Finally slFieldNames.Free; End; aSrc.First; while not aSrc.Eof do Begin aDst.Append; For i := 0 do FieldCount - 1 do dstFields[i].Value := SrcFields[i].Value; aDst.Post; aSrc.Next; End; showmessage('merge '+ aSrc.TableName + ' ok'); End;
procedure TForm1.Button28Click(Sender: TObject); var InputString : string;
begin CopyTables ('R1x.dbf',table1, form2.Table1, 'Name,Vorname,Klasse,Geschlecht,GebDat,Punkte'); CopyTables ('R7x.dbf',table3, form2.Table1, 'Name,Vorname,Klasse,Geschlecht,GebDat,Punkte'); CopyTables ('R8x.dbf',table4, form2.Table1, 'Name,Vorname,Klasse,Geschlecht,GebDat,Punkte'); CopyTables ('R9x.dbf',table5, form2.Table1, 'Name,Vorname,Klasse,Geschlecht,GebDat,Punkte'); CopyTables ('R5x.dbf',table6, form2.Table1, 'Name,Vorname,Klasse,Geschlecht,GebDat,Punkte'); CopyTables ('R6x.dbf',table7, form2.Table1, 'Name,Vorname,Klasse,Geschlecht,GebDat,Punkte'); CopyTables ('Rdx.dbf',table8, form2.Table1, 'Name,Vorname,Klasse,Geschlecht,GebDat,Punkte'); showmessage('MergeFile wurde erzeugt'); end; |
Ungetestet.
_________________ Na denn, dann. Bis dann, denn.
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Fr 10.07.09 19:41
Hi, alzi,
Donnerwetter! Da kann ich was mit anfangen!
Einige Kleinigkeiten habe ich schon beseitigt.
Noch stört die Fehlermeldung: Undefinierter Bezeichner 'afieldnames'
Delphi-Quelltext 1:
| Result.DelimitedText := aFieldNames; |
Bis wann?
Deti 
_________________ ut vires desint, tamen est laudanda voluntas
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 10.07.09 20:05
Oh, sch**** Copy & Paste.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| Function CreateStringListFromCommaString (aCommaText : String) : TStringList; Begin Result := TStringList.Create; Result.Delimiter := ','; Result.DelimitedText := aCommaText; End; |
_________________ Na denn, dann. Bis dann, denn.
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Fr 10.07.09 20:15
Wow, danke für deine prompte Antwort.
_________________ ut vires desint, tamen est laudanda voluntas
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Fr 10.07.09 20:24
Einen "kleinen" hab ich noch zur Laufzeit:
Listenindex überschreitet das Maximum(6)
Wasndas?
_________________ ut vires desint, tamen est laudanda voluntas
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 10.07.09 20:56
D. Annies hat folgendes geschrieben : | Listenindex überschreitet das Maximum(6)
Wasndas? |
Das nennt sich 'Runtime-Error' bzw. Laufzeitfehler. Wieso fragst Du?
Ach, liegt an dem Müll, den ich zusammengetippselt habe...
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| Procedure CopyTables (aTblName : String; aSrc, aDst : TTable; aFieldnames : String); Var srcFields, dstFields : Array Of TField; i : Integer; slFieldNames : TStringList;
Begin aSrc.Close; aSrc.TableName := concat(home, '\', aTblName); aSrc.active := true; slFieldNames := CreateStringListFromCommaString(aFieldNames); Try setLength (srcFields, slFieldNames.Count); setLength (dstFields, slFieldNames.Count);
For i := 0 to slFieldNames.Count - 1 do begin srcFields[i] := aSrc.FieldByname(slFieldnames[i]); dstFields[i] := aDst.FieldByname(slFieldnames[i]); End; Finally slFieldNames.Free; End; aSrc.First; while not aSrc.Eof do Begin aDst.Append; For i := 0 do slFieldNames.Count - 1 do dstFields[i].Value := SrcFields[i].Value; aDst.Post; aSrc.Next; End; showmessage('merge '+ aSrc.TableName + ' ok'); End; |
Und nu?
_________________ Na denn, dann. Bis dann, denn.
Zuletzt bearbeitet von alzaimar am Sa 11.07.09 08:06, insgesamt 1-mal bearbeitet
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Fr 10.07.09 21:55
(klar kenne ich solche Runtime-Errors, aber ich wusste nicht, wo DER herkommt)
Einen hab ich noch:
zur Laufzeit: EConvertError Format '%p' ungültig oder nicht kompatibel mit Argument.
Ist der auch noch von deinem "Geschnipsel"?
Gruß, Deti
_________________ ut vires desint, tamen est laudanda voluntas
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Fr 10.07.09 22:03
Ups, ich meine, ich habe es gesehen: dann muss wohl auch 'Punkte' Integer sein, wa?
Nein, gleicher Fehler - aber es sind ja Integer's in den Tabellen, also doch diese Ecke?
_________________ ut vires desint, tamen est laudanda voluntas
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 10.07.09 23:24
D. Annies hat folgendes geschrieben : | Format '%p' ungültig oder nicht kompatibel mit Argument. Ist der auch noch von deinem "Geschnipsel"? |
Siehst Du '%p' in meinem Cöde?
_________________ Na denn, dann. Bis dann, denn.
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Sa 11.07.09 07:59
Nö, also in meinem Code aber auch nicht. Ich habe jetzt zwei showmessage('hier bin ich') eingebaut, nach den beiden setlength-Anweisungen und nach slFieldNames.free.
Beide Stellen werden noch fehlerfrei erreicht, aber dann kommt die (eine neue) Fehlermeldung: Privilegierte Anweisung
Detlef
_________________ ut vires desint, tamen est laudanda voluntas
|
|
|