AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken TADOQuery.LoadFromFile sehr langsam
Thema durchsuchen
Ansicht
Themen-Optionen

TADOQuery.LoadFromFile sehr langsam

Ein Thema von Bbommel · begonnen am 20. Jun 2012 · letzter Beitrag vom 21. Jun 2012
Antwort Antwort
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
672 Beiträge
 
Delphi 12 Athens
 
#1

AW: TADOQuery.LoadFromFile sehr langsam

  Alt 20. Jun 2012, 17:02
Hm, wäre die Frage, ob ein ClientDataSet die Daten lesen könnte, die von einem ADOQuery (wobei die Funktion von TCustomADODataSet geerbt wird) geschrieben wurde...

Irgendwelche besonderen Events oder so habe ich eigentlich nicht definiert. Die ADOQuery wird zur Laufzeit erzeugt, bekommt beim normalen Import die passende Connection, Cursor und LockType zugewiesen und dann mache ich damit nichts anderes, als diverse Abfragen durchzurattern und die Daten bei mir in lokale Datenstrukturen im Speicher zu importieren.

Dass er versucht, auf die eigentliche Datenbank zuzugreifen, kann eigentlich nicht sein, weil ich die "Connection" in der Query auf nil setze, bevor ich das LoadFromFile aufrufe. Also kennt er die echte Datenbank dann noch nicht mal mehr.

So, "muss" jetzt in den Feierabend. Falls noch jemand Ideen hat, würde ich mich freuen. Nicht wundern, wenn ich selbst erst morgen wieder antworte.

Bis denn
Bommel
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.533 Beiträge
 
Delphi 12 Athens
 
#2

AW: TADOQuery.LoadFromFile sehr langsam

  Alt 20. Jun 2012, 18:30
Notfalls könnte man es vor dem Speichern ja noch schnell umkopieren.

Eventuell/Vermutlich gibt's das auch schon in D2009 ... Delphi-Referenz durchsuchenTDBXDataSetReader ... mit .Create rein und über .CopyReaderToClientDataSet wieder raus.

(Das Ding wird übrigens intern auch vom DataSnap verwendet, für die Übertragung der DataSets, bzw. DataSnap basiert auf dem ganzen DBX-Zeugs )
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
672 Beiträge
 
Delphi 12 Athens
 
#3

AW: TADOQuery.LoadFromFile sehr langsam

  Alt 21. Jun 2012, 11:05
Hier mal ein Update zum Stand der Dinge - mit ein paar neuen Erkenntnissen, auf deren Grundlage vielleicht ja noch jemand einen neuen Tipp hat.

Zunächst zu himitsu: Ja, TDBXDataSetReader gibt es auch schon in D2009 und müsste, da TADOQuery ein Nachfolger von TDataSet ist, auch damit funktionieren. Aber ehrlich gesagt ist mir noch nicht so richtig klar geworden, was ich dann damit machen soll und wie mir das helfen könnte.

Ich habe aber noch ein bisschen weiter geforscht und erste Ergebnisse erzielt, die mich hoffen lassen. Vielleicht hat ja jemand auf dieser Grundlage noch einen entscheidenden Tipp.

Aaaalso: ich habe mir ein kleines Beispielprogramm gebastelt. Dieses greift auf eine wie oben beschrieben von einer Kundendatenbank exportierte Abfrage zurück. Diese Abfrage enthält letztlich Artikeldaten zu ca. 85.000 Artikeln. In meinem kleinen Testprogramm gehe ich diese Daten nur einmal schnell durch und speichere von jedem Artikel die ID in einer Stringliste.

Folgender Code ist dem recht ähnlich, den ich auch in meinem eigentlichen Programm verwende:

Delphi-Quellcode:
procedure Tadospeed_main.ButtonRunSlowClick(Sender: TObject);

var currQuery: TADOQuery;
    i: integer;

begin
  IDList.Clear;
  i:=0;
  currQuery:=TADOQuery.Create(nil);
  currQuery.LoadFromFile(EditFilename.Text);
  while (not currQuery.Eof) do begin
    IDList.Add(currQuery.Fields[0].Value);
    inc(i);
    if i mod 1000=0 then begin
      LabelProgress.Caption:=IntToStr(i);
      Application.ProcessMessages;
    end;
    currQuery.Next;
  end;
  currQuery.close;
  currQuery.free;
end;
So, hier tritt das beschriebene Problem auf. Die ersten 20.000 Datensätze werden in einer knappen Sekunde verarbeitet (ich lasse mir ja den Fortschritt in einem Label anzeigen), danach wird es dann immer langsamer und langsamer.

Aufgrund dieses Verhaltens war meine Vermutung, dass jedes Mal wieder an den Anfang der Datenmenge zurückgesprungen und dann zum gewünschten Datensatz vorgegangen wird. Also irgendwas scheint da mit dem Zeiger schiefzulaufen.

Nun habe ich gesehen: Man kann ja auch direkt auf das "Recordset" zugreifen, ohne irgendwelche Sachen zu nutzen, die Delphi drumrum gebastelt hat. Gesagt, getan:

Delphi-Quellcode:
procedure Tadospeed_main.ButtonRunClick(Sender: TObject);

var currQuery: TADOQuery;
    i: integer;

begin
  IDList.Clear;
  i:=0;
  currQuery:=TADOQuery.Create(nil);
  currQuery.LoadFromFile(EditFilename.Text);
  while (not currQuery.Recordset.EOF) do begin
    IDList.Add(currQuery.Recordset.Fields.Item[0].Value);
    inc(i);
    if i mod 1000=0 then begin
      LabelProgress.Caption:=IntToStr(i);
      Application.ProcessMessages;
    end;
    currQuery.Recordset.MoveNext;
  end;
  currQuery.close;
  currQuery.free;
end;
Und siehe da: Plötzlich dauert das gesamte Verarbeiten der Daten noch nicht mal mehr eine Sekunde. Hmpf.

Das Problem scheint also das "Next" im Query zu sein. Wenn ich also im Recordset direkt mit MoveNext arbeite, dann klappt alles wunderbar. Problem ist nur: dann muss ich auch für das Einlesen mit dem Recordset arbeiten (siehe oben: also Recordset.fields, statt currQuery.Fields). Hier im Beispiel ist das egal, aber im echten Programm hätte das natürlich sehr aufwändige Umbaumaßnahmen zur Folge, da hier doch umfangreiche Datenstrukturen eingelesen werden.

Hat jemand eine Idee, wie man das zusammenbringen kann? Könnte ich der TADOQuery irgendwie klar machen, dass sich das Recordset durch mein MoveNext geändert hat und ich kann dann weiterhin die normalen Eigenschaften/Methoden zum Lesen benutzen?

Bis denn
Bommel
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: TADOQuery.LoadFromFile sehr langsam

  Alt 21. Jun 2012, 14:42
Zunächst würde ich dir ein
Delphi-Quellcode:
IDList.Items.BeginUpdate;
try
...
finally
  IDList.Items.EndUpdate;
end;
empfehlen. Dann probier nachmal das Befüllen aus.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
672 Beiträge
 
Delphi 12 Athens
 
#5

AW: TADOQuery.LoadFromFile sehr langsam

  Alt 21. Jun 2012, 15:26
BeginUpdate/EndUpdate habe ich noch nie bei einer (nicht-visuellen) StringList gebraucht, habe es hier aber trotzdem mal getestet - ich greife ja nach jedem Strohhalm. Leider hat es am Ergebnis aber nichts geändert, d.h. das Verarbeiten ist genauso langsam wie vorher.

Hätte mich auch gewundert, denn in dem Beispiel von mir, in dem ich direkt mit dem "Recordset" arbeite, habe ich ja auch kein BeginUpdate/EndUpdate und die Liste ist in <1 Sek. gefüllt.

Hm. Mittlerweile habe ich auch die Hoffnung etwas aufgegeben und einige besonders zeit-empfindliche Stellen in meinem Code wie beschrieben umgebaut, so dass dieser Import nun so einigermaßen klappt.

Was meint ihr - kann man dieses ungünstige Laufzeitverhalten von Delphi denn als Bug interpretieren, den man mal melden sollte? (wobei vorher zu klären wäre, ob das in XE2 nicht schon besser läuft - wenn hier jemand Zeit/Lust hätte, das mit mir zu testen, kann er sich ja gerne melden)

Bis denn
Bommel
  Mit Zitat antworten Zitat
Iwo Asnet

Registriert seit: 11. Jun 2011
313 Beiträge
 
#6

AW: TADOQuery.LoadFromFile sehr langsam

  Alt 21. Jun 2012, 16:58
Aufgrund dieses Verhaltens war meine Vermutung, dass jedes Mal wieder an den Anfang der Datenmenge zurückgesprungen und dann zum gewünschten Datensatz vorgegangen wird. Also irgendwas scheint da mit dem Zeiger schiefzulaufen.
Wenn das so wäre, würde die Verlangsamung kontinuierlich sein. Du schreibst aber, das das so ab ca. 20.000 langsamer wird. Abrupt, oder wie?
  Mit Zitat antworten Zitat
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
672 Beiträge
 
Delphi 12 Athens
 
#7

AW: TADOQuery.LoadFromFile sehr langsam

  Alt 21. Jun 2012, 17:28
Hiho,

das ist genau so - also die Verarbeitung wird immer langsamer. Ggf. war das ansonsten von mir missverständlich ausgedrückt. Ich habe mal ein kleines Video angefügt, bei dem man den Effekt ganz gut erkennen sollte.
Angehängte Dateien
Dateityp: zip 20120621_1823_05.zip (465,8 KB, 6x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:44 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz