AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Query in thread ausführev: Wie Ergebnis zurück geben

Query in thread ausführev: Wie Ergebnis zurück geben

Ein Thema von norwegen60 · begonnen am 31. Mai 2015 · letzter Beitrag vom 15. Sep 2015
Antwort Antwort
Seite 1 von 2  1 2   
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#1

Query in thread ausführev: Wie Ergebnis zurück geben

  Alt 31. Mai 2015, 23:22
Hallo zusammen,

ich arbeite mit TUniDac und möchte in meiner Anwendung sicherstellen, dass beim Öffnen oder Aktualisieren eine größeren Tabelle die Anwendung nicht einfriert. Dazu habe diverse Artikel gelesen, wie Queries in einem Thread ausgeführt werden können. Ich habe vor, die Connection und die TUniQuery im Thread zu erzeugen. Wie aber übergebe ich die Ergebnismenge an meine Hauptanwendung so dass ich dort mit einer beliebigen Datenbankkomponente (Navigator, dbGrid, ...) darauf zugreifen kann. Die Ergebnismenge wird nur zur Navigation benötigt. Inserts und Edits werden über eine andere UniQuery abgearbeitet.

Bitte keine Ratschläge, dass ich meine SQL-Statements optimieren soll um die Zugriffszeiten herunter zu bekommen. Es geht mir auch ums prinzipielle Threadhandling.

Danke
Gerd
  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
 
#2

AW: Query in thread ausführev: Wie Ergebnis zurück geben

  Alt 31. Mai 2015, 23:39
Du brauchst etwas wie ein ClientDataSet, MemTable, etc.

Die Daten holst du wie jetzt in einem Thread, kopierst die Daten in die MemTable und übergibst nun diese synchronisiert an die Oberfläche.

Dabei würde ich keine Instanz der MemTable in den Thread hineingeben, sondern beim Start der Abfrage die aktuelle MemTable entfernen und im Abfrage-Thread eine neue Instanz der MemTable erstellen.
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
Dejan Vu
(Gast)

n/a Beiträge
 
#3

AW: Query in thread ausführev: Wie Ergebnis zurück geben

  Alt 1. Jun 2015, 07:54
Wenn das die Daten in einzelnen Paketen laden kannst (Pagination), dann würde sich das Problem so nicht stellen, denn dann zeigst Du die 1. Seite und würdest beim Scrollen einfach die nächste Seite laden. Aber das wolltest Du ja so nicht umsetzen, sondern prinzipiell die Vorgehensweise im Thread erklärt haben.

Bei der Pagination hat der Anwender keine Wartezeiten, beim vollständigen Laden der Daten hingegen schon. Denn warten muss der Anwender, aber entweder kann er den Vorgang abbrechen oder eben nicht.

Gut. Die Daten in einem Haps zu laden, hat Sir Rufo schon erklärt. Einige Provider unterstützen das asynchrone Laden von Daten. Der Provider lädt das Ergebnis dann in Stücken. Man gibt bei der Ausführung der Query einen 'Callback' an, der vom Provider dann zwischendurch aufgerufen wird. Nämlich immer dann, wenn der nächste Teil der Ergebnismenge zur Verfügung steht.

Ich weiß nicht, ob UniDac das unterstützt. Es wäre jedoch einen Versuch wert.

Wenn die Ergebnismenge jedoch nicht sonderlich hoch ist, und die Wartezeit aus der Komplexität der Query resultiert, dann muss man sich fragen, ob es sich lohnt, die Abarbeitung in einen Thread zu packen, denn bei einem Abbruch durch den Benutzer muss man ja auch in der Lage sein, die Query abzubrechen.

Vielleicht an dieser Stelle die Frage: Wieso dauert das lange? Komplexe Query oder viele Daten?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Query in thread ausführev: Wie Ergebnis zurück geben

  Alt 1. Jun 2015, 09:17
Zitat:
Bei der Pagination hat der Anwender keine Wartezeiten, beim vollständigen Laden der Daten hingegen schon.
Aber nur, wenn das Zusammenstellen der Daten schnell geht und nur die Übertragung einer großen Menge an Daten zum Clienten lange dauert.
Denn der Server stellt dabei bei sich die Daten erstmal komplett zusammen, vorallem wenn auch noch eine Sortierung enthalten ist und erst danach geht die Übertragung los.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#5

AW: Query in thread ausführev: Wie Ergebnis zurück geben

  Alt 1. Jun 2015, 22:41
Schneller geht es in jedem Fall. Ob es schnell geht, hängt wirklich von der Query ab.
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#6

AW: Query in thread ausführev: Wie Ergebnis zurück geben

  Alt 3. Jun 2015, 10:25
Hallo zusammen,

danke für die Inputs. Bei den Daten handelt es sich um ca 1.2 Mio Datensätze. Das SQL sieht so aus:

SELECT ID, SerNr, Typ, Dat
FROM Ser_Nr
WHERE &ServOrt
ORDER BY SerNr, Dat

und stellt Daten für eine LookUp bereit. Das funktioniert auch, nur dass der Anwender je nach Arbeitsplatz 20-30s warten muss bis die Anwendung gestartet ist (Bei mir lokal dauert es ca. 3s). Und wenn das Laden der Daten in den Hintergrund verlegt werden kann, wäre das super. Ich habe auch schon mit dem Parameter Fetchall rum probiert. Dann wird das Starten zwar schneller, dafür wartet der Anwender aber beim Eingeben, da die Restdaten dann dort geladen werden.

Mit Virtualtable hatte ich bisher nicht gearbeitet, aber die Idee ist gut. Dann könnte ich auch hin und wieder im Hintergrund nachfragen ob auf dem Server neue Daten dazu gekommen sind und diese anfügen. Denn bei einem Refresh wartet der Anwender im Moment halt wieder.

Etwas erstaunt war ich als ich bei mir die Daten zuerst per
  • UniQuery geöffnet habe (ca. 3s)
  • und dann an über VirtualTable1.Assign(UniQuery) zugeordnet habe, was 18s dauerte

Ich habe leider keinen direkten Zugriff auf die langsamen Arbeitsplätze bei meinem Kunden, werde aber bei Gelegenheit schauen wie sich die Zeiten dort verhalten.

Gibt es einen schnelleren Weg von der DB in die VirtualTable?

Grüße
Gerd
:
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Query in thread ausführev: Wie Ergebnis zurück geben

  Alt 3. Jun 2015, 10:36
Ein UniQuery ist auch eine "virtualtable". Du kannst die vorhanden Daten auch nach Schliessen der Verbindung cachen, indem du Disconnected auf True setzt. Zum Kopieren von Daten in eine Virtualtable gibt es auch ein Demo.
Markus Kinzler
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#8

AW: Query in thread ausführev: Wie Ergebnis zurück geben

  Alt 3. Jun 2015, 17:55
...Bei den Daten handelt es sich um ca 1.2 Mio Datensätze. ...und stellt Daten für eine LookUp bereit.
Hmm. Das ist eigentlich Quatsch. Willst Du wirklich alle 1.2 Mio Datensätze präventiv laden? Soll der Anwender wirklich durch 1.2 Mio Zeilen scrollen?

Stell Dir vor, Du hättest -sagen wir- 100 Benutzer. Dann würden beim Programmstart einfach mal eben so ca. pro Benutzer ca. 100 MB (bei 100 Nutzern also 10GB an Daten über das Netz rauschen), und zwar *bevor* die Suche überhaupt losgeht, von der offensichtlichen Wartezeit ganz zu schweigen.

Wenn du z.B. mit Fulltext in der DB suchen könntest, dann könntest Du die Abfragen fast ohne Verzögerung aus der DB laden, und zwar immer nur die, die dem Suchkriterium entsprechen. Über Fulltext-Suche kannst du auch Ähnlichkeitssuchen implementieren, also ähnlich der Google-Suche.

Aber wenn Du unbedingt -aus welchen Gründen auch immer- die 1.2 Mio DS im Speicher benötigst, dann -na ja- dann haust Du die Query in einen Thread, setzt alle Suchfelder und -Buttons auf 'disabled', lädst das Zeugs im Thread und der meldet dann per über sein Terminate-Event den Vollzug. In diesem Event setzt Du dann alle Suchfelder und -buttonis wieder auf 'enabled'. Wupps, kann die Suche losgehen.

Mir allerdings würde das nicht gefallen. Ich würde die Volltext-Option des DB-Servers verwenden, falls der das überhaupt kann, Wenn nicht, würde ich einen Suchserver schreiben, der 1x diese Tabelle aus der DB lädt (und auch komplexe Aktualisierungen des geladenen Bestandes vornehmen kann, denn irgendwann sind die Daten ja doch veraltet). Dieser Server kommuniziert über TCP mit den Clients bzw. anders herum: Die Clients fragen den Server nach einer Teilliste, die den Suchkriterien entspricht.

Hier sind Anregungen für Delphi-Fulltextsuche

http://stackoverflow.com/questions/9...ird-and-delphi
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#9

AW: Query in thread ausführev: Wie Ergebnis zurück geben

  Alt 3. Jun 2015, 23:30
Hallo,

ich wusste dass dies Antwort über kurz oder lang kommt . Natürlich scrollt der Benutzer nicht durch die Datensätze, sondern er gibt in die Lookupcombo die Serien-Nr. ein und die Combo vervollständigt das Suchwort und springt mit jedem Tip näher an die Nr. Da die Serien-Nr. mehrfach da sein kann oder er die Nr. nicht genau weiß, scrollt er zuletzt auf den gewünschten Satz. Ich habe auch schon probiert, die LookUp so zu ändern, dass sie beim schnellen Tippen gar nicht erst versucht zu suchen sondern erst wenn der Benutzer langsamer tippt, aber so richtig rund lief das nicht.

Die Lookup-Combo (TdbLookupComboPlus) stammt noch aus Paradox-Zeiten und die Anwender haben sich ziemlich daran gewöhnt, dass sie mehr oder weniger in Echtzeit durch die Daten blättern. Nur bei der Serien-Nr.-Verwaltung ist es aufgrund der Datenmenge problematisch. Mit der arbeiten aber nur ca. 10-15 Personen und die starten auch nicht gleichzeitig. Um die Datenmenge zu reduzieren, lade ich eigentlich auch nur ein paar Felder.

Das größere Problem ist aber in der Tat, dass die lokalen Daten irgendwann veraltet sind. Deshalb auch die Idee mit dem Thread der am Anfang im Hintergurnd die Daten läd und dann immer wieder eventuell geänderte Daten nach lädt. Die Erkennung ist kein Problem, da alle Datensätze ein Zeitstempel haben.

Danke fürs Feedback
Gerd
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#10

AW: Query in thread ausführev: Wie Ergebnis zurück geben

  Alt 4. Jun 2015, 07:41
Die Antwort kam in der Sekunde, in der Du "1.2 Mio" und "Lookup" genannt hast. Es ist mir schon klar, das das ganz gut funktioniert. Welche DB verwendest Du? Ich habe eine Echtzeitsuche mit MS SQL-Server ohne Probleme hinbekommen, die Antwortzeit liegt im Bereich von 100ms. Bei 1.2 Mio records wirst Du aber auch in-Memory mit Verzögerungen zu rechnen haben, insofern dürfte die einfache Volltextsuche wirklich schneller sein. Wenn Du die Möglichkeit hast.

In einem anderen Fall musste der Kunde (ein Großhändler) sehr schnell in 10-100 Tausend Aufträgen suchen (Tabelle mit 250 Feldern). Ca. 50 Benutzer nutzen diese Funktion. Die Lösung war hier der TCP-Server, der die Aufträge in XML in-Memory hält. Der Client schickt eine Suchanfrage als Key-Value-Liste ('Feld', 'Suchtext') und bekommt seine Antwort in Sekundenbruchteilen. Da auch das Speichern über den Suchserver läuft, waren die Daten immer auf dem aktuellen Stand.

Das sind natürlich alles nur Vorschläge, denn wenn deine Lösung soweit gut funktioniert, dann bleib dabei. Ich frage mich gerade, wie man sucht, während die Daten gerade aktualisiert werden... Du musst dann natürlich die Daten in einer zweiten Tabelle aktualisieren und erst wenn alle Daten da sind, 'umschalten'.

Aber wenn Du den Zeitstempel hast, musst Du ja eh nur die Änderungen nachladen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 16:04 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