Einzelnen Beitrag anzeigen

peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
672 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: TIBCQuery funktionsweise ?

  Alt 17. Apr 2019, 12:33
Guten Tag,

Kann mir jemand erklären wie die TIBCQuery komponente oder allgemein wie Query Komponenten funktionieren ?

Ich will wissen wo die abgefraten Daten abgelegt werden. Werden die Daten im Client-Memory abgelegt ?
Sind alle abgefragten Daten im Memory vorhanden bis zum nächsten Query ?
Oder wird bei jeder qryAnweisung der Server abgefragt ?

Beispiel
Delphi-Quellcode:
qryMitarbeiter.Open;
Name := qryMitarbeiterName.AsString;
Wird nun bei dem Befehl "qryMitarbeiterName.AsString;" eine Server abfrage gemacht? Order werden die Daten aus dem Client-Memory geholt?

Mfg Int3g3r
Bei allen mir bekannten Server-Datenbanken läuft das so:

Query.Open schickt die Abfrage an den Server, und der Server erstellt einen Satz von Zeilen (Records), die den Bedingungen der Abfrage genügen, so wie zu diesem Zeitpunkt in der Datenbank existieren. Der Server hält dieses Ergebnis quasi vorrätig, solange die Query noch offen ist, oft als Teil einer automatischen Transaktion, die erst geschlossen wird, wenn die Query vom Client geschlossen wird. Aus diesem Satz von Records wird oft auch erstmal nur ein Teil an den Client zurückgegeben, der Rest dann erst, wenn der Client durch die Records scrolled (lazy fetch). Je nach Server und Art der Abfrage kann es sogar sein, das der Server zuerst nur einen Teil des Resultats zusammensucht und zurückgibt, den Rest dann erst, wenn der Client mehr Records anfordert (delayed fetch). Das ist z. B. der Grund, wieso man bei einer Query gemeinhin erst weis, wieviele Records sie liefert, wenn man bis zum letzten Record durchgescrollt hat.

Der Client kann, muss aber nicht, die bisher zurückgegebenen Records intern speichern. Verlassen kann man sich nur drauf, dass der aktive Record (der auf dem der Cursor der Query steht) vollständig im Client memory ist, und daher ein Zugriff auf dessen Felder keinen Serverzugriff auslöst. Eine Ausnahme sind mitunter BLOB-Felder, deren Inhalt oft erst vom Server geholt wird, wenn der Client ihn abfragt. Das sind alles Optimierungen, um den Datenverkehr zwischen Client und Server möglichst klein zu halten, da der Datentransfer früher (und oft auch heute noch) der limitierende Faktor für die Performance der Query war.

Der Server trifft aber auf jeden Fall Vorkehrungen dafür, dass der Client nur Records zurückbekommt, die der query zum Zeitpunkt ihrer Ausführung entsprechen. Wenn die Query längere Zeit offen bleibt und derweil Änderungen an dem Inhalt der Datenbank gemacht werden tauchen diese neuen Datensätze nicht automatisch im Resultat der Query auf, auch wenn sie der Abfrage entsprechen würden. Das kann für den Server ein ziemlicher Aufwand sein, er muß dafür quasi einen Snapshot der von der Query angesprochenen Tabellen erstellen und vorrätig halten, bis die Query geschlossen wird. Nur so kann sowas wie delayed fetch implementiert wwerden.

Wenn man also mit queries gegen eine Server-Datenbank arbeitet, sollte man immer
  • die query möglichst spezifisch formulieren, um einen möglichst kleinen Ergebnissatz zu erzeugen.
  • die query möglichst schnell wieder schließen, um die verwendeten Resourcen auf dem Server wieder freizugeben.

Wenn man die Daten aus der Query clientseitig länger braucht sollte man sie vollständig im Client speichern, z. B. in einem TClientDataset, oder (meine bevorzugte Methode) in einer Liste von Objekten.

Wenn der Client Änderungen an der Datenbank durch andere Beutzer mitbekommen muss, kann das aufwendig werden, je nach verwendeter Server-Datenbank. Interbase, Firebird und Oracle (die einzigen DBs die ich wenigstens ein bißchen kenne) haben eine Benachrichtigungsmechanismus, mit dem der Server dafür angemeldete Clients über interessante Änderungen informieren kann. Das erfordert aber gemeinhin auch einige server-seitige Programmierung (Trigger zumeist). Wenn die Datenbank sowas nicht anbietet sollte der Client dem Benutzer eine Refresh-Option für die angezeigten Query-Resultate anbieten, die die Query neu ausführt. Das automatisch alle x Sekunden zu machen ist normalerweise keine gute Idee, zumindest bei nicht lokal installierten Datenbanken.
Peter Below
  Mit Zitat antworten Zitat