Einzelnen Beitrag anzeigen

Partikelecho

Registriert seit: 2. Dez 2011
14 Beiträge
 
Delphi 6 Enterprise
 
#1

Insert-Schleife viel zu langsam

  Alt 2. Dez 2011, 08:20
Datenbank: DBISAM • Version: 4 • Zugriff über: DBISAMQuery
Guten Morgen,
Ich bin neu hier, also verzeiht mir eventuell falsch genutzte Foren, o.ä. fürs Erste.

Meine Aufgabe ist das Programmieren einer Anwendung zum Auslesen von Ordnern (welche immer eine Datenbank sind, also Pfad = Datenbank) und das darstellen der Dateiinformationen in einem DBGrid.

Ich verwende Delphi 6 und soweit ich weiß DBISAM 4 (kann ich im moment nicht überprüfen).
Mein Problem ist, dass zwar die FindAllFiles-Funktion und die Variablenzuweisung in der Schleife relativ schnell gehen, das Inserten von 40.000 Datensätzen in etwa 8 bis 10 Minuten dauert.

- Version mit Parametern statt direkter Variablenübergabe ist noch langsamer
- Bulkinsert von jeweils 50, 100 oder 1000 SQL-Inserts dauert in etwa genau so langsam.
- Die Funktionen GetFileTimes & GetFileSize laufen auch nur ein paar Sekunden.
- Kommentiere ich den SQL-Teil ab with aus, so dauert es ebenfalls nur ca. 10 Sekunden (gut, immernoch zu lange, aber im Vergleich zu Minuten..)
- SL[i] (eine Stringlist) enthält die einzufügenden Dateien.

Delphi-Quellcode:
procedure TFRM_Main.ReadInInvA;
var
  i, invasize:Integer;
  inva, invaaccessed, invacreated, invamodified:String;
  created, accessed, modified:TDateTime;
begin
  QRY_Container.SQL.Clear;
  inva := invaname;
  for i := 0 to SL.Count-1 do
  begin
    if GetFileTimes(CXBE_DbDir.Text+’\‘SL[i], created, accessed, modified) then
    begin
      invaaccessed := DateTimeToStr(accessed);
      invacreated := DateTimeToStr(created);
      invamodified := DateTimeToStr(modified);
    end;
    invasize := GetFileSize(CXBE_DbDir.Text’\‘+SL[i]);
    with QRY_Container do
    begin
      SQL.Add(’INSERT INTO ‘inva’(INVA_FILE, INVA_FILE_CREATED,‘+
              ’INVA_FILE_ALTERED, INVA_FILE_VIEWED, INVA_FILE_SIZE) VALUES’+
              ’ (’’’+SL[i]‘’’,‘’’invacreated+’’’,‘+
              ’’’’+invamodified+’’’,’’’+invaaccessed+’’’,‘inttostr(invasize)’);’);
      if i > 0 then
      begin
        if (i mod 1000) = 0 then
        begin
          ExecSQL;
          SQL.Clear;
        end;
      end;
      if i = SL.Count-1 then
      ExecSQL;
      // 1000 Insert-Befehle werden hintereinander geschrieben und dann zusammen ausgeführt.
    end;
  end;
end;
  Mit Zitat antworten Zitat