Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Query in thread ausführev: Wie Ergebnis zurück geben (https://www.delphipraxis.net/185329-query-thread-ausfuehrev-wie-ergebnis-zurueck-geben.html)

norwegen60 31. Mai 2015 22:22

Query in thread ausführev: Wie Ergebnis zurück geben
 
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

Sir Rufo 31. Mai 2015 22:39

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
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.

Dejan Vu 1. Jun 2015 06:54

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
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?

himitsu 1. Jun 2015 08:17

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
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.

Dejan Vu 1. Jun 2015 21:41

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
Schneller geht es in jedem Fall. Ob es schnell geht, hängt wirklich von der Query ab.

norwegen60 3. Jun 2015 09:25

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
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
:

mkinzler 3. Jun 2015 09:36

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
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.

Dejan Vu 3. Jun 2015 16:55

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

Zitat von norwegen60 (Beitrag 1304004)
...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

norwegen60 3. Jun 2015 22:30

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
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

Dejan Vu 4. Jun 2015 06:41

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
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.

Jasocul 4. Jun 2015 07:04

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
Vielleicht einfach mal das Konzept überdenken? Oder den Anwendern erklären, dass sie entweder 20-30 Sekunden warten müssen, wenn sie die gewohnte Bedienung nicht ändern wollen?
Du steckst jetzt viel Zeit in deine ganzen Überlegungen und Klimmzüge. Manchmal muss man dem Anwender auch mal zumuten, dass sich was ändert.

Ich hatte vor Jahren etwas ähnliches.
Mit den Datenmengen war die Bedienung nicht akzeptabel. Also habe ich das Lookup nachgebildet, aber etwas umgesetzt, was du auch schon angedeutet hast. Erst ab einer gewissen Anzahl an Buchstaben werden überhaupt Daten geholt. Zusätzlich habe ich die Pausen zwischen den Tastenanschlägen geprüft und erst, wenn offensichtlich nichts mehr getippt wird, die DB-Abfrage angestoßen. Die Kombination dieser beiden Dinge hat sehr gut funktioniert. Bei mir waren es mindestens 3 Zeichen und die Pause größer als 300 Millisekunden, wenn ich mich richtig erinnere.
Also einfach mal dein Standard-Lookup rausschmeißen und was eigenes programmieren. Was ich damals gebastelt hatte, war nicht wirklich kompliziert. Außerdem spart man sich auf diese Weise auch noch die Hintergrundprüfung, ob die Daten aktualisiert werden müssen. Der lokale Rechner und das Netzwerk werden vermutlich auch nicht mehr so stark belastet. Das hängt natürlich auch von den Daten ab, die dort vorliegen.

P.S.:
Ich gehe mal davon aus, dass du eine vernünftige Indexierung auf den Such- und Sortierfeldern hast.

Dejan Vu 4. Jun 2015 07:29

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
In der Steuerungstechnik nennt man das 'entprellen'. Das geht mit einem Timer sehr einfach: Den Timer auf 300ms einstellen und bei jedem Tastendruck im Suchfeld (OnKeyUp) neu starten. D.h. solange man tippt, passiert nichts. Erst wenn man nicht tippt, wird automatisch nach 300ms der Timerevent aufgerufen der als erstes den Timer selbst deaktiviert und dann prüft, ob man die Daten nachladen kann/muss (Length>3 o.ä.)

Diesen kleinen Trick kann man immer dann verwenden, wenn man implizit etwas nachladen muss. So habe ich eine Report-Preview gebaut: Eine lange Liste von Reports wird im Grid angezeigt und daneben die Preview. Wenn man im Grid die Zeile wechselt, wird der entsprechende Report angezeigt. Beim Scrollen würde sich der PC aber einen Wolf rendern und das ganze ruckelt doch ganz schön: Also diesen Timer eingebaut und Ruhe im Karton. Billiger Trick, aber sehr effektiv.

norwegen60 4. Jun 2015 13:09

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
Ich verwende MsSQL. Wenn die Daten mal geladen sind, ist ein Schnelltipper immer noch behindert. Ich habe aber gefragt was den Anwendern lieber ist "Daten sofort zu sehen" oder "Schneller tippen zu können" und die Mehrzahl ist für Daten sehen, Kritikpunkt ist eigentlich nur die Ladezeit. Und der Plan war eben, die Daten im Hintergrund zu laden und dann zu aktivieren und danach nur noch die Änderungen zu aktualisieren.
Zitat:

Manchmal muss man dem Anwender auch mal zumuten, dass sich was ändert
Das ist genau die Einstellung, die ich den meisten Programmierern vorwerfe. Sie denken, die Welt dreht sich um sie, dabei dreht sie sich um die Anwender. Ich bin eben der Meinung es ist einfacher ein Programmierer steckt etwas Gehirnschmalz in ein Problem als wenn sich zig User mit dem Problem rumschlagen (Oder auch nur ein User, der aber Tag für Tag). Und deshalb ist es eben einfacher ich stecke Zeit in ein Problem als dass sich die Anwender ärgern. Zumal ich gleichzeitig auch Anwender bin.
Als ich das Thema vor 5 Jahren mal diskutiert habe, hat jeder gemeint dass die Funktion im Zeitalter von SQL-Datenbanken keiner mehr braucht. Google-Sei-Dank wissen mittlerweile die meisten, dass es eben doch sinnvoll ist. Auch wenn der Programmierer nicht gleich eine Lösung hat.

Das mit der Zeitverzögerung hatte ich schon mal implementiert, das ist aber nicht so gelaufen wie ich wollte. Werde aber auch hier mal Zeit investieren. Wenn aber die Ladezeit reduziert werden kann, da der Prozess im Hintergrund läuft, wäre mein Problem schon wesentlich entspannt (Außer der Netzwerkler kommt und meint sein Netz sei überlastet)

Grüße
Gerd

Olli73 4. Jun 2015 14:02

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

Zitat von norwegen60 (Beitrag 1304146)
Als ich das Thema vor 5 Jahren mal diskutiert habe, hat jeder gemeint dass die Funktion im Zeitalter von SQL-Datenbanken keiner mehr braucht. Google-Sei-Dank wissen mittlerweile die meisten, dass es eben doch sinnvoll ist.

Google ist ein gutes Beispiel. Die schaffen es, unmittelbar nach einem Tastendruck Suchvorschläge aus Milliarden(?) von Suchbegriffen zu machen, und das über eine popelige Internet-Leitung. Oder laden die sich etwa vorher ihren kompletten Index auf meinen Rechner?


Wenn die Daten trotzdem unbedingt komplett geladen werden sollen, würde ich mal überlegen, diese dann lokal zu speichern (und laden). Eine Update-Funktion willst du ja eh einbauen.

Jasocul 4. Jun 2015 14:11

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

Zitat von norwegen60 (Beitrag 1304146)
Zitat:

Manchmal muss man dem Anwender auch mal zumuten, dass sich was ändert
Das ist genau die Einstellung, die ich den meisten Programmierern vorwerfe. Sie denken, die Welt dreht sich um sie, dabei dreht sie sich um die Anwender.

Ich bin da völlig auf deiner Seite. Ich habe das vielleicht etwas ungeschickt ausgedrückt.
Es ging nur darum, dass man die gewohnte Bedienung verändert, damit es für den Anwender komfortabler wird. Andere (akzeptable) Bedienung mit mehr Geschwindigkeit.

Perlsau 4. Jun 2015 17:19

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

Zitat von Olli73 (Beitrag 1304151)
Google ist ein gutes Beispiel. Die schaffen es, unmittelbar nach einem Tastendruck Suchvorschläge aus Milliarden(?) von Suchbegriffen zu machen, und das über eine popelige Internet-Leitung. Oder laden die sich etwa vorher ihren kompletten Index auf meinen Rechner?

Google arbeitet mit einer ganz besonderen und – soweit mir bekannt – auch einmaligen Rechner-Verclusterung:

Ein weiteres Ergebnis der internen Entwicklungsarbeit ist das GOOGLE FILE SYSTEM (GFS), gewissermaßen das Nervensystem von GOOGLE. Grundlage für das GFS, das auf fast allen GOOGLE-Computern läuft, war das Quellcode-offene Betriebssystem Linux. Das GFS weiß, welche Informationen wo in dem riesigen Datenmeer liegen. Es steuert GOOGLEs riesige Computerverbände. Diese sogenannten Cluster bestehen aus einigen 100 oder sogar aus mehr als 5000 Computern. Das GFS hält sie zusammen. Fallen Rechner aus, fängt das System diese Pannen auf. Um Datenverluste zu verhindern, speichert das GFS jede Datei mindestens drei Mal. Selbst wenn der Betrieb nicht normal läuft, spürt das GFS in Windeseile die Daten aus dem Datenbestand auf, der geographisch am nächsten beim Nutzer liegt, oder von den Rechnern, die die meisten Ressourcen frei haben und damit am schnellsten arbeiten. Fallen ein paar Computer plötzlich aus, holt sich die Software die Daten einfach von einem der anderen Rechner.

Statt nach dem perfekten Computer zu suchen, gingen GOOGLEs Netzwerkingenieure immer davon aus, daß sich Hardware-Ausfälle ohnehin nicht vermeiden lassen. Sie versuchten erst gar nicht, besonders gute Computer zu konstruieren, sondern verwendeten ihren Einfallsreichtum darauf, Maschinen schnell aus dem Verbund heraustrennen und neue Rechner einbauen zu können. Entsprechend haben die Software-Ingenieure das GFS aufgebaut: »Es muß fortlaufend sich selbst überwachen und Komponentenausfälle entdecken, aushalten und sich schnell wieder von ihnen erholen«, schreiben sie in einem Fachartikel.


Quelle: Lars Reppesgaard, "Das Google Imperium – Google kennt dich besser, als du denkst", ISBN 978-3-86774-046-3, 2008 Murmann Verlag GmbH, Hamburg

Captnemo 4. Jun 2015 18:02

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
1,2 Mio Datensätze auf Verdacht zu laden, weil gerade mal einige benötigt werden...

Wenn es sich dabei doch um Seriennummern handelt, die ja sowieso per Hand eigegeben werden, dann reicht es doch sicherlich aus, die benötigten Lookup-Daten erst zu holen, wenn die Anzahl der eingegeben Daten eine sinnvolle Vorauswahl zulassen (denn vorher blättert doch eh keiner) und damit die Datenmenge massiv einschränken.

Ansonsten mach es doch so, wie schon mit einem Timer vorgeschlagen:

Oder so.
Benutzer Tippt Zeichen
-> Thread starten um die Ergebnismenge erst mal zu holen
Tippt der Benutzer jetzt nächstes Zeichen, bevor der Thread beendet ist, dann
-> Thread abbrechen -> neuen Thread starten
usw.
Wenn aber Ergebnismenge zur Verfügung steht, bevor der Benutzer ein weiteres Zeichen eingegeben hat, dann kannst du ja die Ergebnismenge in dein Lookup kopieren.

Da der Benutzer eh auf die Ergebnismenge warten muss, wird er wahrscheinlich ein weiteres Zeichen eingeben, und dann brauchst du ja die vorherige Ergebnismenge nicht mehr, da sie Daten enthält, die eh nicht in Frage kommen.
Ich habe leider keine 1,2 Mio. Datensätze zur Hand, sonst würde ich es ausprobieren. Aber ich könnte mir gut vorstellen, dass es so ohne lästige Eingabepause recht flüssig laufen könnte.

Dejan Vu 4. Jun 2015 22:04

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

Zitat von norwegen60 (Beitrag 1304146)
Ich verwende MsSQL. Wenn die Daten mal geladen sind, ist ein Schnelltipper immer noch behindert.

Wie meinst Du das? Wie, wann ist ein 'Schnelltipper' behindert? :shock:

Ich kenne aber das Problem: Inkrementelle Suche 'while you type' ist schon charmant. Da dabei sehr viele -ziemlich bescheuerte- Abfragen an den SQL-Server gestellt werden, ist eine im-Memory Suche hier wirklich richtig.

Ich habe dafür einen Dienst geschrieben, der die Daten beim Hochfahren lokal auf den Client-PC saugt und auch die Aktualisierung vornimmt. Der Client (also die Anwendung) redet über COM mit dem lokalen Dienst, um die Filterung vorzunehmen. Ich zeige auch nur die ersten 1000 Records an, weil durch die scrollt eh keine Sau. Aber die 'Suchzeiten' sind im Bereich von < 20ms pro Tastendruck, also brauche ich noch nicht einmal die Entprellung.

Durch das Laden der Daten beim Rechnerstart entfällt auch die lange Wartezeit beim Start des Programms.

Allerdings ist das Suchen in 1.2 Mio DS in wenigen Millisekunden nicht trivial, vor allen Dingen bei den ersten paar Zeichen. Aber da gibt's auch Tricks.

juergen 14. Sep 2015 21:22

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

2 Monate später;-)
Auch ich wurde schon einige Male "gezwungen" alle Daten clientseitig zu laden so dass der Anwender in zig Millionen Datensätzen suchen kann...

Ich habe gerade mal mit einer In-Memory-Testumgebung in Form einer TStringList() getestet.
Folgende Bedingungen:
Suchwort = 3 Zeichen
Suchstring pro Zeile = 70 Zeichen lang

Bei 3 Mio Datensätzen (= 27,3 MB RAM) benötigt die Standardsuche mit Pos() ca. 977ms.
Ich vermute, dass meine ausgesuchten Bedingungen nicht so gut sind wie deine, von daher wird wahrscheinlich diese Suche auf deine Ergebnismenge angewendet noch einiges schneller sein. Wenn du nur nach Zahlen suchst wird die Suche nochmals geschätzte 6-10x schneller sein.

Bei 1,2 Mio Datensätzen (= 13,4 MB RAM) benötigt mein Test 391 ms. Wenn man die schon genannten Such-Bedingungen berücksichtigt (Timer-Event über 300ms beim Tastendruck und erst nach 3 Zeichen suchen lassen), scheint eine einfache In-Memory-Suche ausreichend, oder?

Dejan Vu 15. Sep 2015 06:34

AW: Query in thread ausführev: Wie Ergebnis zurück geben
 
Mittlerweile habe ich mit der Volltextsuche von Microsoft sehr gute Ergebnisse erzielt. Dabei ist die Suchgeschwindigkeit bei > 10 Mio Records im Bereich von 100ms. Natürlich, ohne die Daten vorher in den Speicher zu laden.

Wenn man dann noch Pagination einsetzt, ist man dann schon ziemlich nahe an Google ;-)

Auch über das Internet.

Der 'Nachteil' der Volltextsuche ist hier imho gleichzeitig ein Vorteil. Man kann nur nach Wortanfängen suchen. "Delp*" findet "Delphi", aber "*elphi" findet gar nichts. Dafür ist eine Synonymliste, Verbreflexion etc. schon eingebaut. Wer will, kann 'Meyer', 'Maier', 'Mayer' und 'Meier' zusammenfassen.


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