Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Firedac Query fetch all (https://www.delphipraxis.net/194024-firedac-query-fetch-all.html)

MES 9. Okt 2017 09:48

Datenbank: MariaDB • Version: 10.1.13 • Zugriff über: Firedac

Firedac Query fetch all
 
Hallo miteinander.
Ich hab da ein Problem das uns seit Tagen beschäftigt: Das Öffnen einer Query fürt bei einer bereits geöffneten Query zu einem "Fetch all" auf der vorher schon geöffnet Query.

Beispiel:

query1.open('select * from xx' ); RowSetSize=50; Ergebnis: 50 Datensätze -> ok

query2.open('select * from yy' ); Fetch All; Ergebnis query2:ok ABER Query1 hat nun nicht mehr 50 Datensätze sondern ALLE Datensätze (z.B. 100.000)

Gemeinsamkeiten:
1) Querys sind in Datamodule - aber in unterschiedliche
2) Benutzen die gleiche Connection
3) InnoDB
4) Beide Querys haben Indizierte Felder (Indexname)

Es gibt keinerlei Verbindungen/Relations zw. den Querys

Und noch was: Bei manchen Querys gibt es nicht dieses Verhalten, bei anderen jedoch immer.

Hat jemand eine Idee wie ich das umgehen kann oder was ich falsch mache?

MES 9. Okt 2017 11:09

AW: Firedac Query fetch all
 
Es scheint als kämen wir der Ursache näher: wenn beide Query auf die gleiche Art (z.B. Conection) dann tritt der Fall auf. Wird eine über Conection und die Andere über Connactionname angesprochen ist es so wie es sein soll(kein Fetch All auf Query1)

jobo 9. Okt 2017 11:20

AW: Firedac Query fetch all
 
Ich kenne die Firedac Kompos nicht, aber es ist wohl eher so, dass fetchall auf eine gesamte Connection angewendet wird. Wenn Du nun mit Connection Alternativen rumwuselst, läuft es wahrscheinlich darauf hinaus, dass 2 separate Connections verwendet werden.
Das funktioniert also dann auf die Art eher nicht für beliebig viele Queries.
Man müsste gezielt neue Connections erzeugen oder noch viel besser:
Die Datenmengen sofort so filtern, dass nur die gewünschte Menge angezeigt wird bzw. mit Where Clause in den Queries arbeiten.

MES 9. Okt 2017 11:45

AW: Firedac Query fetch all
 
Danke für die Rückmeldung, ich befürchte es könnte sich bewahrheiten was Du schreibst. Dann kick ich das Ganze in den Papierkorb und setze wieder Table statt Query ein.

Nehmen wir an, Query1 wäre ein Artikelstamm in dem oft gescrollt wird etc. und das Query2 Zahlungsbedingungen sind.
Wie soll ich den Artikelstamm eingrenzen, nach welchen Kriterien? Und warum? Nur weil ich eine zweite Query mit 20 Datensätze aufmache? Das Fetchen der Daten mit Rowsetsize=50 geht recht fix aber in meinem Beispiel hat der Artikelstamm z.B. 100.000 Datensätze (kann auch eine Million oder mehr haben). Das eigenmächtige Einlesen dieser Datensätze nur weil ich eine 2. Query öffne dauert nicht nur lange (6-7 Sekunden) sondern ist auch unnötig - aus meiner einfachen Sicht als BDE-Umsteiger (von TTable).

Ich vermute eher das es sich um einen Bug handelt. Frage: Ist dieses Verhalten unter anderen Datenbanken auch so?

jobo 9. Okt 2017 12:59

AW: Firedac Query fetch all
 
Ich hatte diese FetchAll Geschichte eher für ein älteres Problem gehalten.
Wie auch immer, ich arbeite immer mit Where Clause und ich denke, das ist nicht unüblich. FetchAll sind für mich begrifflich sehr nahe an cursor Implementierungen,die sehr spezifisch (Herteller) sein können.
Jede Komponente macht es auch etwas anders, bei Ado sind es maxrecords oder so einfach als Attribut des Dataset.
Denen "goldenen" Weg bei Diredac kenne ich nicht.

Wenn Du Table "gewohnt" bist, musst Du Dich wohl an Query und Where Clause gewöhnen oder solltest zumindest. Das Öffnen einer großen Datenmenge auf dem Server erzeugt auch eine erhebliche Last, ohne dass alle Sätze übertragen werden. Das will man nicht, insbesondere nicht in Mehrbenutzerumgebungen. Sehr leicht verständlich, wenn man sich Umgebungen wie Facebook o.ä. anschaut. Da wird natürlich nicht eine ganze User Table geöffnet nur weil sich einer anmeldet.

MES 9. Okt 2017 15:38

AW: Firedac Query fetch all
 
Hast ja recht. Deswegen grenze es ja ein:
query1.open('Select * from Artikelstam where Artikeltyp='P') -> ergibt eine Datenmenge von sagen wir mal größer 50. Durch die Rowsetsize werden die ersten 50 geladen.

Nun kommt eine 2 Query die ich öffnen will. Die hat so wenige Datensätze, dass sich eine "where" nicht lohnt (kleiner 50).

query2.open('Select * from Zahlungsbedingungen' ). Jetzt wird bei der Query1 die Rowsetsize automatisch verworfen und es werden alle Datensätze eingelesen.
Selbst wenn ich in der query2 auch ein "where" einbaue (über Parameter) bleibt das Ergebnis unverändert. Zum besseren Verständnis ein weiteres Beispiel: query2 sind Lagerorte auf denen dieser Artikel gelagert ist. Im oberen Grid navigiert man über die Artikel und im unteren Grid werden die Lagerorte angezeigt. Quasi Master/Detail. Kann man sich leich mit Rechungen/Positione etc. auch vorstellen.

Doch ob ich wie oben beschrieben oder die Querys wahllos zum Testen öffne - es erfolgt immer ein "Aushebeln" der Rowsetsize und ein fetch all der query1 ist die Folge. Selbst wenn die Querys in keinerlei Beziehungen zueinander stehen. Es sieht aus, als ob beim Öffnen der 2. Query ein "disconnect" stattfindet um die 2. Query zu connecten und bei dem erneuten Connect der 1. Querry ein fetch all stattfindet. IRRE.

MES 9. Okt 2017 16:11

AW: Firedac Query fetch all
 
Tagesabschlussmeldung: Es scheint am Verbindungsmanager zu liegen. Diesen verwenden wir um aus einer Ini die Werte raus zu lesen(Typ Persistent).
Stellen wir die Connection ohne den Manger her(in der Entwickungsumgebung) ist alles ok. Es funktioniert auch sauber (also kein fetch all) wenn wir die Verbindung im Quellcode vornehmen. Juhuuuu!!!

Morgen wird intensiv getestet und geforscht - ich werde berichten.

Frickler 10. Okt 2017 11:10

AW: Firedac Query fetch all
 
Zitat:

Zitat von MES (Beitrag 1382892)
Nehmen wir an, Query1 wäre ein Artikelstamm in dem oft gescrollt wird etc

Ja die Freuden der "visuellen Selektion": viele Anwender suchen lieber in einem Grid mit 100.000 Zeilen nach einer Artikelnummer anstatt diese eben in ein Feld einzugeben, Enter, und da hamwer den Artikel...

MES 10. Okt 2017 14:49

AW: Firedac Query fetch all
 
Testen und verzweifeln ist angesagt. Ich bin sehr geneigt den FirDreck raus zu hauen. Wir drehen uns noch immer im Kreis, mal tuts und mal nicht :wall:

Jetzt sind wir so weit, dass in einem Testprojekt alles funzt, im eigentlichen Projekt aber gar nicht bzw. wie beschrieben.
Im Testprojekt funzt es mit dem FDManager nicht, d.h. es wird automatisch ein Fetch all ausgeführt. Ohne den Manger ist es gut.

Wir bauen jetzt Modul für Modul, Komponente für Komponente in das Testprojekt ein - bis es hoffentlich klar ist was dieses absonderliche Verhalten auslöst.

jobo 10. Okt 2017 15:14

AW: Firedac Query fetch all
 
Also ich hab irgendwo gelesen, das Fetchall Problem ist ein BDE MS Treiber / Provider Problem.
Ggf. habt Ihr irgendwo noch leichen im Keller, ein bisschen BDE, ein alter Treiber, ...

bnreimer42 10. Okt 2017 15:48

AW: Firedac Query fetch all
 
Also laut http://docwiki.embarcadero.com/Libra...taSet.FetchAll bezieht sich FetchAll nur auf das aktuelle Resultset.

Ich verwende FetchAll manchmal, wenn ich nicht eh FetchOptions.Mode auf fmAll gesetzt habe, um alle Datensätze in einem Grid anzuzeigen und hatte da noch nie Nebenwirkungen. Allerdings habe ich mit MariaDB noch nie gearbeitet.

Aber ein kurzer Blick in die MySQL FireDAC Doku bringt den Parameter ResultMode zum Vorschein. Wie ist der denn gesetzt? Wenn der auf Store steht, würde das erklären, wo die Daten des zweiten Resultsets herkommen, denn dann macht er immer FetchAll.

himitsu 10. Okt 2017 17:40

AW: Firedac Query fetch all
 
Vielleicht kann hier irgendwer nur eine gleichzeitige Verbindung aufrechterhalten? (FireDAC, DB-Treiber, Datenbank-Server, DBMS, ....)
Bzw. man muß erst irgendwo aktivieren, dass mehrere Verbindungen gehen?

Also sobald über die selbe Connection nun was Neues geht, wird die andere Verbindung getrennt (und vorher noch schnell alles geholt).

MES 11. Okt 2017 15:23

AW: Firedac Query fetch all
 
So, wir haben das Problem erheblich einkreisen - aber noch nicht ganz lösen können.

In einem Initbereich war folgendes hinterlegt:
stLibFile := ExtractFileDir(stABSEXE) + '\lib\libmysql.dll';
md.FDPhysMySQLDriverLink1.VendorLib := stLibFile;

Den angegebenen Pfad gab es aber gar nicht. Statt einer Fehlermeldung auszugeben wurde intern danach gesucht(weil es in den uses steht?) und eine Version von libmysql.dll von 2015 genommen. Hm, ganz schön alt dachte ich und durchsuchte meinen PC nach weiteren libmysql.dll. Ich fahnd in einem Ordner eine weitere lib mit dem Datum 2001. Ich biege
also den obigen Quellcode auf diesen Ordner hin und siehe da! Es funktioniert!!! Das FetchAll ist weg!!! Genau das hätte ich aber nicht erwartet den der Treiber ist uralt.

Noch bissl Verwirrung: Ich fand die FireDacAdministrator.exe. Hier wird genau diese uralte Version von libmysql.dll angezeigt. Kein Problem dachte ich, ich stell den Pfad auch hier um - doch wie? In der ConnectionDef.ini ist kein Pfad eingetragen. Weiß jemand wo/wie dieser Pfadeintrag editierbar ist? Oder was die aktuelle Version von libmysql ist?

MES 11. Okt 2017 16:05

AW: Firedac Query fetch all
 
Libmysql haben wir in der Version .19 von MySql runtergezogen.... bin gespannt.. morgen gibts news. Danke erstmals für eure Hilfe.

MES 13. Okt 2017 09:01

AW: Firedac Query fetch all
 
Es ist leider wie befürchtet: Mit dem Uralttreiber(2001) funktioniert es und mit jedem neuerem nicht. Um alle eventuelle Altlasten zu umgehen wurde ein neues Projekt erzeugt und auf einer neu aufgesetzten VM getestet.
Bin nun echt ratlos und frage mich ob der Wechsel von der Uralt(aber funktionierender) BDE zu neueren(aber nicht funktionierenden) Technologien der richtige Weg war. Wo ich hinlang nur Mist. Nicht mal der einsatz von TFDTable funktioniert denn hier führt die unterschiedliche Sortierung des Client und des Servers zu dopellten Zeileneinträge und somit zu einer Fehlermeldung. Auch dieses Problem wird im Internet seit vielen Jahren immer wieder erkannt(auch hier im Forum) doch eine Lösung scheint keiner zu haben. Die vagen Aussagen von Embarcadero versteh ich jetzt endlich richtig: Müll ist Müll und kann nicht zu Gold gemacht werden. Embarcadero ist auf dem sicheren Weg einen seit 20 Jahren (ab Delphi 2) glühenden Fan zu verlieren. Wünsche euch ein schönes Wochenende und hoffe das ihr mehr Erfolg hattet als ich.

MES 13. Okt 2017 12:36

AW: Firedac Query fetch all
 
Wir haben einen Test mit myDac (anstatt FireDac) gemacht - alles funzt wie es soll, also ist dieses ominöse "fetch all" beim "open" weg. FireDac fliegt höchstwahrscheinlich raus.

Hat jemand mit myDac bzw. UniDac Erfahrungen? Spricht was dagegen diese einzusetzen? In Verbindung mit MariaDb. Erste Tests haben zumindest ein deutlich schnelleres Fetching
gezeigt(doch das müssen wir genauer testen).

mkinzler 13. Okt 2017 13:05

AW: Firedac Query fetch all
 
Nicht mit MySQL/MariaDB. Aber allgemein recht gute Erfahrungen mit UniDAC.

mikhal 13. Okt 2017 13:47

AW: Firedac Query fetch all
 
Ich habe sehr gute Erfahrungen mit UniDAC machen können. Erwähnenswert ist auch das mitgelieferte Migrationstool um von BDE, den eigenen und fremden DACs (auch von FireDAC nach UniDAC) zu konvertieren.

Grüße
Mikhal


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:27 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