ich habe hier einen code geschrieben, der super funktioniert.
Aus einer Datenbank, will ich einen Datensatz nach dem anderen mit den anderen Datensätzen vergleichen und anschließend modifiziert in eine CSV speichern.
Mit dem Vergleichen, modifizieren und CSV ist kein problem und funktioniert alles.
Das Problem sind eher die Datensätze. Wenn es 10 Datensätze sind, läuft alles schön schnell. Aber sobald es mehr werden, 50, 100, 200,1000,... dauert es sehr lange.
Das Problem ist vermutlich die doppelte Schleife.
Angenommen, für einen Datensatz benötigt das ganze 1 Sekunde (zum rechnen).
Mit der doppelten Schleifen wären das dann a*b=Dauer
Und dann kann man sich ausrechnen, dass die Dauer schnell expontiell in die Höhe schießt. Und die Dauer dann schnell bei ein paar Stunden oder länger sein kann.
Gibt es irgendwelche Tricks um solche Vorgänge zu beschleunigen?
Code: Alles auswählen
procedure TForm1.Button4Click(Sender: TObject);
var
a,b,z: integer;
texta: TStringList;
berechnung,berechnung2,sqla: string;
startTime: Cardinal;
temp: string;
ziel: integer;
begin
// [...]
sqla := 'SELECT * FROM db a, ue b where a.bID = b.ID; ';
ZQuery1.Close;
ZQuery1.SQL.Clear;
ZQuery1.SQL.Add(sqla);
ZQuery1.Open;
ZQuery2.Close;
ZQuery2.SQL.Clear;
ZQuery2.SQL.Add(sqla);
ZQuery2.Open;
// [...]
for a:=0 to ZQuery1.RecordCount-1 do begin // ==== Erste Schleife
z:=0;
if (trim(ZQuery1.FieldByName('vt').AsString)) = '' then begin // wenn leerer datensatz dann weiter
ZQuery2.First; // und jetzt wieder auf den Anfang setzen!
ZQuery1.Next;
continue;
end;
berechnung2 := '';
// csv:
berechnung2 := berechnung2 + ZQuery1.FieldByName('b').AsString+','+ZQuery1.FieldByName('k').AsString+','+ZQuery1.FieldByName('vn').AsString+'; ';
for b:=0 to ZQuery2.recordCount-1 do begin // ==== Zweite schleife berechnung
if (ZQuery2.FieldByName('a1').AsString+' '+ZQuery2.FieldByName('k').AsString+','+ZQuery2.FieldByName('vn').AsString) = ZQuery1.FieldByName('a1').AsString+' '+ZQuery1.FieldByName('k').AsString+','+ZQuery1.FieldByName('vn').AsString
then begin // gleichen datensatz nicht mehr anschauen
ZQuery2.next;
continue;
end;
if (trim(ZQuery2.FieldByName('vt').AsString)) = '' then begin // wenn leerer datensatz dann weiter
ZQuery2.next;
continue;
end;
// === Eigentliche Anwendung
if ( berechneB(ZQuery1.FieldByName('vt').AsString, ZQuery2.FieldByName('vt').AsString ) >= ziel ) then begin
berechnung2 := berechnung2+ ZQuery2.FieldByName('a1').AsString+' '+ZQuery2.FieldByName('k').AsString+','+ZQuery2.FieldByName('vn').AsString+'/';;
z:=z+1;
end;
ZQuery2.Next; //a) nächster Datensatz
end; //for zweite schleife prüfung
// [...]
ZQuery2.First; //b) und jetzt wieder auf den Anfang setzen!
ZQuery1.Next;
end; // for erste Schleife
end;