Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi ADO langsam :-( (https://www.delphipraxis.net/192080-ado-langsam.html)

haentschman 18. Mär 2017 14:10

Datenbank: MSSQL • Version: 2012 • Zugriff über: ADO

ADO langsam :-(
 
Hallöle... :P

Ich bin am Verzweifeln... :?

Ich muß 50000 Datensätze in eine generische Liste laden. Soweit so gut... Das SQL holt die Daten über eine Query ab. Das dauert max. eine Sekunde.
Und jetzt kommts... Die Schleife bis EOF dauert 25 Sekunden. :shock: ...auch wenn ich die Schleife nackig ohne Inhalt laufen lasse. :shock:
Delphi-Quellcode:
while not Query.Eof do
begin
  Blubb := TBlubb.Create;
  Blubb.Caption := DataSet.FieldByName('Bla').AsString;
  List.Add(Blubb);
end; // ca. 25 Sekunden
Die Query wird immer neu erzeugt. Es sind keine Events eingehängt. An welcher Schraube muß ich drehen das der Durchlauf besser wird?
Als Vergleich: Mit NEXUS passiert das nicht. Da ist die Schleife in ca. 2 Sekunden durch.

Das hat nichts mit der DB als solches zu tun... sondern mit ADO. Ich weiß schon warum ich die hasse...:evil:

Danke.

p80286 18. Mär 2017 14:19

AW: ADO langsam :-(
 
Vor langer,langer Zeit hat Gerhard etwas dazu geschrieben, ich hab die Details leider nich mehr im Kopf, unter der Delphi Schicht gibt es so etwas ähnliches wie resultrecords, die sind sauschnell.

Gruß
K-H

haentschman 18. Mär 2017 14:28

AW: ADO langsam :-(
 
Danke...

Die Query stammt aber aus einer Abstraktionsschicht für verschiedene DBMS. Da komme ich nicht dran... :? Ich habe nur die TDataSet Methoden verfügbar.

LÖSUNG:
TDataSet.DisableControls :gruebel: Obwohl keine Controls oder Events dranhängen ist es nun mit einer Sekunde deutlich schneller. :thumb: Ohne Worte...:?

Again what learned...:stupid:

mensch72 18. Mär 2017 15:00

AW: ADO langsam :-(
 
noch schneller wird es, wenn du nicht bei jedem Schleifendurchlauf fas Feld über den Feldnamen "suchst"..

also besser vor der Schleife
field : TField;
field := DataSet.FieldByName('Bla');

in der Schleife:
Blubb.Caption := field.AsString;

p80286 18. Mär 2017 15:54

AW: ADO langsam :-(
 
Zitat:

Zitat von haentschman (Beitrag 1364646)
LÖSUNG:
TDataSet.DisableControls :gruebel: Obwohl keine Controls oder Events dranhängen ist es nun mit einer Sekunde deutlich schneller. :thumb: Ohne Worte...:?

Again what learned...:stupid:

Kein DBGrid oder ähnliches??
Gruß
K-H

haentschman 18. Mär 2017 16:01

AW: ADO langsam :-(
 
:P
Zitat:

Kein DBGrid oder ähnliches??
...nö. :wink: Nackige Datenbankabfrage und packen in eine Liste. Da müssen trotzdem irgendwelche Eventorgien ablaufen. :?

Uwe Raabe 18. Mär 2017 16:08

AW: ADO langsam :-(
 
Zitat:

Zitat von mensch72 (Beitrag 1364650)
noch schneller wird es, wenn du nicht bei jedem Schleifendurchlauf fas Feld über den Feldnamen "suchst"..

Seitdem TDataSet die Zuordnung Feldname/Feld in einem TDirctionary vorhält, ist der dadurch erreichte Vorteil nicht mehr so groß wie er früher mal war.

p80286 18. Mär 2017 16:12

AW: ADO langsam :-(
 
Zitat:

Zitat von haentschman (Beitrag 1364657)
:P
Zitat:

Kein DBGrid oder ähnliches??
...nö. :wink: Nackige Datenbankabfrage und packen in eine Liste. Da müssen trotzdem irgendwelche Eventorgien ablaufen. :?

:gruebel: Mal sehen ob ich nächste Woche etwas Zeit finde.
Ein gewisser Vista-Fan wird zwar sagen, das ist ein toter Gaul:wink:, aber vielleicht macht es den einen oder anderen glücklich.

Welche DB und welcher Provider? Vielleicht sitzt da der Schmutzfink.

Gruß
K-H

haentschman 18. Mär 2017 16:24

AW: ADO langsam :-(
 
:P
Zitat:

Welche DB und welcher Provider? Vielleicht sitzt da der Schmutzfink.
...falsch. :wink: (MSSQL 2012, ADO)
siehe:
Zitat:

Das SQL holt die Daten über eine Query ab. Das dauert max. eine Sekunde.
... das ist in Ordnung. :wink:
Zitat:

Die Schleife bis EOF dauert 25 Sekunden. ...auch wenn ich die Schleife nackig ohne Inhalt laufen lasse
... das nicht. :evil:
Zitat:

das ist ein toter Gaul
...ich habe mir die ADO nicht ausgesucht. :cry:
Zitat:

Mal sehen ob ich nächste Woche etwas Zeit finde.
...für mich brauchtst du keine Zeit mehr investieren. Ich habe fertig... :thumb:

Aviator 18. Mär 2017 19:30

AW: ADO langsam :-(
 
Zitat:

Zitat von haentschman (Beitrag 1364661)
Zitat:

das ist ein toter Gaul
...ich habe mir die ADO nicht ausgesucht. :cry:

Was würdet ihr denn in Verbindung mit MSSQL empfehlen? Also was die Standardkomponenten angeht die bei Delphi 10.1 Berlin dabei sind?!

mikhal 19. Mär 2017 11:25

AW: ADO langsam :-(
 
FireDAc von Embarcadero oder UniDAC von Devart.

Wobei FireDAC bei der Professional- Version von Delphi / RAD Studio nur mit Addin MS SQL Server kann oder mit der Enterprise-Version von Delphi / RAD Studio.

Grüße
Mikhal

Bernhard Geyer 19. Mär 2017 12:03

AW: ADO langsam :-(
 
Und wenn du keine DB-Sensitiven Controls an TDatasets hängst kannst du auch den nativen ADO-Interfaces (Also ohne dbGO-Schnittstelle von Emba) dich dran hängen.

haentschman 19. Mär 2017 16:41

AW: ADO langsam :-(
 
Zitat:

UniDAC von Devart.
[Meine Meinung]
...die beste Investion ever. 8-)
[/Meine Meinung]

Bernhard Geyer 19. Mär 2017 18:39

AW: ADO langsam :-(
 
Zitat:

Zitat von haentschman (Beitrag 1364759)
Zitat:

UniDAC von Devart.
[Meine Meinung]
...die beste Investion ever. 8-)
[/Meine Meinung]

Sind voll ihr Geld Wert (ebenfalls meine Meinung).
Haben Sie Jahrelang für MySQL im Einsatz (DAC for MySQL) und haben jetzt im Rahmen einer Vereinheitlichung auch den Oracle-Zugriff darüber laufen.

haentschman 20. Mär 2017 12:50

AW: ADO langsam :-(
 
Hallöle... :P

Hier ist das Problem nochmal beschrieben:
https://edn.embarcadero.com/article/27790
Zitat:

I noticed, while accessing some 25,000 rows of SQL Server data in a TADOQuery, that simply looping through the rows of the TADOQuery took 75 seconds, while performing NO work of any type within the loop.

sko1 20. Mär 2017 12:58

AW: ADO langsam :-(
 
Wenn ich das richtig sehe betrifft dieses Problem auch die Firedac TFDQuery ?

Ciao
Stefan

Bbommel 20. Mär 2017 13:48

AW: ADO langsam :-(
 
Wenn ich jetzt nicht alles völlig falsch verstanden habe, dann muss ich aber die ADO-Komponeten auch mal ein bisschen in Schutz nehmen - von Haus aus verhalten die sich nicht so, wie du es beschreibst. :-) Du schreibst ja, dass du die Objekte aus irgendeiner Abstraktionsschicht zur Verfügung gestellt bekommst, auf die du selbst keinen Einfluss hast. Wahrscheinlich werden dort irgendwelche fiesen Sachen gemacht. ;)

Ich benutze TADOConnection und TADOQuery seit vielen Jahren für Zugrife auf den MS SQL Server und importiere damit zehntausende Datensätze in wenigen Sekunden. Die hier genannte Option musste ich noch nie ändern (ich hatte am Anfang nur Probleme mit Cursor-Locations und so, aber das lag an mir und konnte ich mit Hilfe hier aus der DP lösen).

Was ich damit sagen will: Die Devart-Komponenten sind super und ich nutze die auch an anderer Stelle. Aber wenn man die noch nicht hat und nicht kaufen mag und nur mal schnell den Zugriff auf den SQL Server braucht, dann geht das auch heutzutage mit dem ADO-Zeug noch ganz problemlos.

haentschman 20. Mär 2017 15:11

AW: ADO langsam :-(
 
:P
Zitat:

dass du die Objekte aus irgendeiner Abstraktionsschicht zur Verfügung gestellt bekommst, auf die du selbst keinen Einfluss hast.
...dort werden fiese Sachen wie der Wechsel des DBMS gemacht. Dort wird die TNxQuery zur TADOQuery. :zwinker: Letzendlich bleibt es aber auch eine ADOQuery. :zwinker: Das einzige was ich nur machen kann, ist auf der TDataSet Ebene. Da komme ich an die CursorLocation der Connection etc. nicht dran...ist aber auch nicht notwendig, weil die Abstraktionsschicht das regeln muß. :wink:
Zitat:

Aus dem Embarcadero Artikel: "SQL Server data in a TADOQuery"
...ich bin nicht allein. :zwinker:
Zitat:

Die hier genannte Option musste ich noch nie ändern
...mach doch mal einen Test bei dir mit Zeitvergleichen mit 100000 Objekten in einer Schleife. :thumb:

Bbommel 20. Mär 2017 16:07

AW: ADO langsam :-(
 
Ich ziehe alles zurück und behaupte das Gegenteil. :-) Weil hier immer vom Server die Rede war, habe ich zuerst nicht weit genug gedacht (außerdem ist ja Montag ;) ), denn eigentlich habe ich auch schon ziemlich lange ein ähnliches Problem mit TADOQuery: wenn ich die Daten direkt vom Server hole, dann läuft, wie beschrieben, alles ganz wunderbar und ich habe die beschriebenen Performanceprobleme tatsächlich nicht. Aber: ich nutze von der ADOQuery die Funktionen LoadFromFile und SaveToFile. Wenn beim Kunden Probleme in den Daten auftreten, dann kann ich die beim Kunden mit SaveToFile in eine Datei schreiben und bei mir mit LoadFromFile wieder so importieren, als kämen sie direkt aus der Datenbank. Total praktisch, um Fehler zu analysieren.

Dabei war es nun so, dass das LoadFromFile bei mir ab einem bestimmten Umfang der Daten unglaublich langsam wurde. Das war immer sehr lästig (aber bisher doch selten genug, sodass ich einfach damit gelebt habe, zumal es ja nur mich beim Analysieren betrifft und nicht die Kunden direkt), aber ich bin dem Problem irgendwann nicht mehr weiter nachgegangen.

Ausgehend von deinem Beitrag und jetzt, wo ich heute Nachmittag doch mal mehr Zeit hatte, habe ich mir den Blog-Eintrag mal näher angeschaut und dachte mir, könnte doch auch für mich passen. Und tatsächlich: ein Aufruf von myQuery.DisbaleControls hat jetzt beim Test mit einem umfangreichen Datensatz die Importzeit von 110 Sekunden auf 20 Sekunden verkürzt. Cool. 8-)

Immer schön, wenn man unerwartet Lösungen für Probleme findet, bei denen man eigentlich schon resigniert hat. Danke dir also für den Thread und die Lösung!

nahpets 20. Mär 2017 16:10

AW: ADO langsam :-(
 
Meine praktische Vorgehensweise, wenn ich in 'ner Schleife While not EoF über 'nen Dataset laufen muss:

Immer vorher DisableControls, egal um was für eine Datenbankkomponente und / oder Datenbank es sich handelt.

Machts (fast) immer deutlich schneller.

Egal ob ADO oder Zeos oder die schöne, alte TTable und per BDE ...

Sofern ein DataSet 'ner DataSource zugewiesen ist, hilft es, wenn's um Geschwindigkeit geht, ab und an auch, wenn man vorher der DataSource den DataSet auf NIL setzt und am Ende DataSet wieder zuweist.

p80286 20. Mär 2017 16:25

AW: ADO langsam :-(
 
Wow, ich hab es auch einmal ausprobiert
a) Ausgabe in ein tMemo 70.000 pro Minute
b) Ausgabe in ein tStringgrid 20.000 pro Minute

Nachher:
a) tMemo 250.000 in 50 sec (davon 13 für das Denken der DB)
b) tStringgrid 250.00 65 sec.

Bei einem Verifikationslauf schwankte die Zeit um ca. 5 Sec.

Aber das ist mir jetzt auch egal.

Gruß
K-H

haentschman 20. Mär 2017 16:26

AW: ADO langsam :-(
 
Zitat:

beim Test mit einem umfangreichen Datensatz die Importzeit von 110 Sekunden auf 20 Sekunden verkürzt.
... das deckt sich mit anderen Aussagen, das die Zeit sich auf ca. 30% vom Vorwert einpendelt. :thumb:

Ich sags ja immer wieder: Again what learned...:stupid:

p80286 20. Mär 2017 16:30

AW: ADO langsam :-(
 
Jo darauf muß man erst einmal kommen.

Denn in der D/ Hilfe steht:
Zitat:

Die Methode DisableControls deaktiviert die Aktualisierung der datensensitiven Steuerelemente, die mit der Datenmenge verbunden sind.

Delphi-Syntax:

procedure DisableControls;

C++ Syntax:

void __fastcall DisableControls(void);

Beschreibung

Rufen Sie DisableControls vor dem Verarbeiten einer großen Anzahl von Datensätzen auf, damit die datensensitiven Steuerelemente nicht bei jeder Änderung des aktiven Datensatzes aktualisiert werden. Auf diese Weise kann die ständige Bildschirmaktualisierung verhindert und die Verarbeitung beschleunigt werden, da die Daten nicht laufend auf dem Bildschirm ausgegeben werden müssen.

Wenn die Steuerelemente noch nicht deaktiviert sind, hält DisableControls den aktuellen Status der Datenmenge fest, benachrichtigt die verbundenen datensensitiven Steuerelemente und Detaildatenmengen von der Statusänderung und inkrementiert den Deaktivierungszähler der Datenmenge. Andernfalls wird lediglich der Deaktivierungszähler inkrementiert.

Der Deaktivierungszähler wird intern verwendet, um zu bestimmen, ob Daten in den datensensitiven Steuerelementen angezeigt werden sollen. Enthält die Zählervariable einen Wert größer Null, werden die Daten nicht aktualisiert.

Ist die Datenmenge die Hauptmenge einer Haupt/Detail-Beziehung, wird durch den Aufruf von DisableControls auch diese Beziehung deaktiviert. Wenn Sie BlockReadSize anstelle von DisableControls verwenden, wird die Detaildatenmenge beim Durchlaufen der Datenmenge aktualisiert, die datensensitiven Steuerelemente jedoch nicht.

Hinweis: Aufrufe von DisableControls können verschachtelt werden. Dabei muss jedoch für jeden Aufruf von DisableControls ein entsprechender Aufruf von EnableControls stattfinden, da sonst datensensitive Steuerelemente und Detaildatenmengen nicht aktualisiert werden.
Warum also sollte ich Disablecontrols verwenden, wenn ich mit Datensensitiven Komponenten nichts am Hut habe?
:wall:

Gruß
K-H

nahpets 20. Mär 2017 16:41

AW: ADO langsam :-(
 
Zitat:

Zitat von p80286 (Beitrag 1364854)
Warum also sollte ich Disablecontrols verwenden, wenn ich mit Datensensitiven Komponenten nichts am Hut habe?
:wall:

Gruß
K-H

Naja, ganz einfach:

Es wird permanent nachgeschaut, ob es eventuell was zu aktuallisieren gibt.

Mit DisableControls wird nicht mehr nachgeschaut.

DataSet weiß halt nicht, ob irgendwelche Komponenten dranhängen, deshalb muss das geprüft werden. Jedes Mal.

DisableControls sagt halt: Spar die die Prüfung (und natürlich dann auch alles das, was da noch dranhängt).

Schnellermachen geht auch noch anders:

Vor der Schleife das Programm minimieren, nachher wieder zurück auf vorherigen Zustand.
Minimiert muss nix Neumalen. Neumalen dauert.

haentschman 20. Mär 2017 16:55

AW: ADO langsam :-(
 
Zitat:

DisableControls sagt halt: Spar die die Prüfung (und natürlich dann auch alles das, was da noch dranhängt).
...wenn aber die DataSource = nil ist da würde ich erwarten das die Prüfung eingespart wird. :gruebel:

Alles andere müßten wir am Code der ADOQuery analysieren...wer hat Zeit. :stupid:

nahpets 20. Mär 2017 17:04

AW: ADO langsam :-(
 
Zitat:

Zitat von haentschman (Beitrag 1364860)
Alles andere müßten wir am Code der ADOQuery analysieren...wer hat Zeit. :stupid:

Nein, das Problem kenn' ich von allen Datenbankkomponenten, das ist nicht typisch ADOQuery.

Die ADO-Schnittstelle selbst ist wohl auch nicht die Schnellste. Da summieren sich dann unterschiedliche "Spaßbremsen".

p80286 20. Mär 2017 17:44

AW: ADO langsam :-(
 
[OT]
Da meine SQL-Oberfläche mit den erstgenannten Werten immer noch die Profi-Oberfläche der Datenbank schlägt, scheint in den verschiedenen Zugriffskomponenten (nicht nur Delphi) einiges an Optimierungspotential zu schlafen.
[/OT]

Gruß
K-H

nahpets 20. Mär 2017 18:18

AW: ADO langsam :-(
 
Ohja, das langsamste an den Datenbanken sind die Oberflächen.

Bei Mengenoperationen sollte man tunlichst auf deren Verwendung verzichten bzw. alles, was mit Optik zu tuen hat, auf ein Minimum reduzieren.

haentschman 21. Mär 2017 05:41

AW: ADO langsam :-(
 
Moin...:wink:
Zitat:

Da meine SQL-Oberfläche mit den erstgenannten Werten immer noch die Profi-Oberfläche der Datenbank schlägt
...wie muß man sich das, auch optisch, vorstellen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz