Filtern von rel. grossen Datenmengen [erledigt]
Moderator: Moderatoren
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Filtern von rel. grossen Datenmengen [erledigt]
Hi,
bei einer meiner Kunden taucht folgendes Problem auf. Es gibt eine Tabelle mit ca. 50.000 Datensätzen (Rechnungen). Mit einem Filter
"set filter to ..." setze ich z.B. das Rechnungsjahr als Filter. Das Ergebnis sind ungefähr 10.000 Rechnungen. Das Fatale ist, daß das GO TOP nach der Filterdefinition ca. 10 Sek. dauert, dann startet erst die DO WHILE Schleife. Die gesamte Prozedur dauert ungefähr 30 Sek. Warum dauert das "GO TOP so lange?
Das Thema ist bis jetzt nicht aufgefallen, da die Tabelle noch wesentlich kleiner war.
Gibt es eine andere Methode als "SET FILTER TO... ", um eine gefilterte Menge von Datensätzen auszugeben?
Gruß Wolfgang
bei einer meiner Kunden taucht folgendes Problem auf. Es gibt eine Tabelle mit ca. 50.000 Datensätzen (Rechnungen). Mit einem Filter
"set filter to ..." setze ich z.B. das Rechnungsjahr als Filter. Das Ergebnis sind ungefähr 10.000 Rechnungen. Das Fatale ist, daß das GO TOP nach der Filterdefinition ca. 10 Sek. dauert, dann startet erst die DO WHILE Schleife. Die gesamte Prozedur dauert ungefähr 30 Sek. Warum dauert das "GO TOP so lange?
Das Thema ist bis jetzt nicht aufgefallen, da die Tabelle noch wesentlich kleiner war.
Gibt es eine andere Methode als "SET FILTER TO... ", um eine gefilterte Menge von Datensätzen auszugeben?
Gruß Wolfgang
Zuletzt geändert von Wolfgang_B am Di, 03. Dez 2019 9:52, insgesamt 1-mal geändert.
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2825
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 96 Mal
- Danksagung erhalten: 13 Mal
Re: Filtern von rel. grossen Datenmengen
Hallo, Wolfgang -
wen der Filter-Begriff als erster Schlüssel in einem Index verwendet wird, könntest Du mal dbSetScope() anschauen.
wen der Filter-Begriff als erster Schlüssel in einem Index verwendet wird, könntest Du mal dbSetScope() anschauen.
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Filtern von rel. grossen Datenmengen
Hallo Georg,
funktioniert das auch bei einem zusammengesetzen Index? Hier z.B. Rechnungsjahr+Rechnungsart+Kundennummer ..
funktioniert das auch bei einem zusammengesetzen Index? Hier z.B. Rechnungsjahr+Rechnungsart+Kundennummer ..
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2825
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 96 Mal
- Danksagung erhalten: 13 Mal
Re: Filtern von rel. grossen Datenmengen
Hallo, Wolfgang -
aus meiner Erfahrung: ja. Alaska empfiehlt in der Dokumentation, einen Schlüssel zu verwenden, der einen String ergibt. Dann arbeitet der dbSetScope() mit dem linken Teilstring. Einfach ausprobieren.
aus meiner Erfahrung: ja. Alaska empfiehlt in der Dokumentation, einen Schlüssel zu verwenden, der einen String ergibt. Dann arbeitet der dbSetScope() mit dem linken Teilstring. Einfach ausprobieren.
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Filtern von rel. grossen Datenmengen
wenn der Index Ausdruck "so kurz" ist gibt es keine Probleme aber CDX hat z.B. eine Beschränkung auf 120 Zeichen.Wolfgang_B hat geschrieben: ↑So, 01. Dez 2019 19:56 funktioniert das auch bei einem zusammengesetzen Index? Hier z.B. Rechnungsjahr+Rechnungsart+Kundennummer ..
bei 2 x Felder a 80 Zeichen könnten dann Probleme entstehen.
---
ich hatte es, bevor SCOPE kam, so gelöst.
Code: Alles auswählen
SEEK(cFilter)
IF FOUND()
nRec := RECNO()
SET FILTER TO &cFilter
GOTO(nRec)
gruss by OHR
Jimmy
Jimmy
- Jan
- Marvin
- Beiträge: 14653
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Re: Filtern von rel. grossen Datenmengen
Hallo Wolfgang,
Scopes sind so richtig schnell, ihc arbeite da viel mit. Nachteil gegenüber den Filtern: Die sind nicht so flexibel, oder manchmal nur mit Klimmzügen. Wenn Du nur das Rechnungsdatum brauchst, kannst Du den Index natürlich einfach auf Year(cAlias->rechnungsdatum) setzen. Wenn Du mehr brauchst mag es notwendig sein, das komplexer aufubauen. So werte ich dann z. B. den Feldinhalt aus, und setze das als .T. bzw. .F. in den Index ein. Einfach weil zwei Werte von - bis in einem Scope schlichtweg nicht gehen.
Manchmal arbeite ich auch mit SCOPE_TOP UND SCOPE_BOTTOM. Meistens mit SCOPE_BOTH, aber manchmal komme ich halt nur mit der Unterteilung weiter.
Es gibt übrigens den PDR 7226 vom 27.11.2019 der besagt, das DbSetcope() ein Memory-Leck hat. Leider hat es für November kein Update gegeben, ich hatte schon gehofft die würden das schnell fixen.
Jan
Scopes sind so richtig schnell, ihc arbeite da viel mit. Nachteil gegenüber den Filtern: Die sind nicht so flexibel, oder manchmal nur mit Klimmzügen. Wenn Du nur das Rechnungsdatum brauchst, kannst Du den Index natürlich einfach auf Year(cAlias->rechnungsdatum) setzen. Wenn Du mehr brauchst mag es notwendig sein, das komplexer aufubauen. So werte ich dann z. B. den Feldinhalt aus, und setze das als .T. bzw. .F. in den Index ein. Einfach weil zwei Werte von - bis in einem Scope schlichtweg nicht gehen.
Manchmal arbeite ich auch mit SCOPE_TOP UND SCOPE_BOTTOM. Meistens mit SCOPE_BOTH, aber manchmal komme ich halt nur mit der Unterteilung weiter.
Es gibt übrigens den PDR 7226 vom 27.11.2019 der besagt, das DbSetcope() ein Memory-Leck hat. Leider hat es für November kein Update gegeben, ich hatte schon gehofft die würden das schnell fixen.
Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9361
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 101 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: Filtern von rel. grossen Datenmengen
Man kann Scopes und Filter aber auch kombinieren. Und damit kann man die meisten „unscharfen“ Situationen abdecken. 10 Sekunden bei nur 50.000 Datensätzen sind aber auch bei einem Filter zu viel. Das könnte an gelöschten Sätzen liegen. Da hilft ein gelegentliches DBPack().
Herzlich,
Tom
Tom
- Jan
- Marvin
- Beiträge: 14653
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Re: Filtern von rel. grossen Datenmengen
Tom,
das stimmt natürlich. Ich hatte das auch mal versucht, das hat mir aber nicht so wirklich den gewünschten Geschwindigkeitsvorteil gebracht. Deswegen bin ich dann auf die etwas komplexeren Scopes ausgewichen.
Jan
das stimmt natürlich. Ich hatte das auch mal versucht, das hat mir aber nicht so wirklich den gewünschten Geschwindigkeitsvorteil gebracht. Deswegen bin ich dann auf die etwas komplexeren Scopes ausgewichen.
Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9361
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 101 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: Filtern von rel. grossen Datenmengen
Hallo, Jan.
Wenn man viel löscht, aber selten packt, sind konditionale Index zu empfehlen (FOR !Deleted()). Das hilft auch bei Filtern, wenn ein solcher Index führend bleibt. Scopes und Filter lassen sich sehr gut kombinieren, wenn die Scopes eine ausreichend präzise Vorauswahl treffen. Wenn ich alle Rechnungen suche, bei denen der Bemerkungentext ein bestimmtes Wort enthält, und die in einem Zeitraum zwischen x und y erzeugt worden sind, wird der Filter auf "c $ bemerkungen" nie deutlich langsamer als das Durchskippen aller Datensätze im Scope. Ein Filter auf "d >= x .and. d <= y .and. c $ bemerkungen" muss aber alle Datensätze bis zum ersten Treffer prüfen.
Ggf. kann auch SET SMARTFILTER ON ein bisschen helfen. Das bewirkt, dass sich Xbase++ die Treffer eines Filters merkt und nicht mehr auswerten muss. Manch ein Filter ist auch langsam, weil häufiger als nötig in der Tabelle navigiert wird, was dazu führt, dass die Filterausdrücke immer wieder evaluiert werden müssen. Mit Smartfilter geschieht das nur einmal, und das Workspace-Objekt merkt sich die Treffer - bis zum nächsten DbRefresh(). Funktioniert gut, und wenn nichts anderes als ein Filter geht, weil alle Anfragen zu unscharf sind oder die Benutzer ihre Abfragen völlig frei selbst bauen können, ist es das Hilfsmittel der Wahl.
Wenn man viel löscht, aber selten packt, sind konditionale Index zu empfehlen (FOR !Deleted()). Das hilft auch bei Filtern, wenn ein solcher Index führend bleibt. Scopes und Filter lassen sich sehr gut kombinieren, wenn die Scopes eine ausreichend präzise Vorauswahl treffen. Wenn ich alle Rechnungen suche, bei denen der Bemerkungentext ein bestimmtes Wort enthält, und die in einem Zeitraum zwischen x und y erzeugt worden sind, wird der Filter auf "c $ bemerkungen" nie deutlich langsamer als das Durchskippen aller Datensätze im Scope. Ein Filter auf "d >= x .and. d <= y .and. c $ bemerkungen" muss aber alle Datensätze bis zum ersten Treffer prüfen.
Ggf. kann auch SET SMARTFILTER ON ein bisschen helfen. Das bewirkt, dass sich Xbase++ die Treffer eines Filters merkt und nicht mehr auswerten muss. Manch ein Filter ist auch langsam, weil häufiger als nötig in der Tabelle navigiert wird, was dazu führt, dass die Filterausdrücke immer wieder evaluiert werden müssen. Mit Smartfilter geschieht das nur einmal, und das Workspace-Objekt merkt sich die Treffer - bis zum nächsten DbRefresh(). Funktioniert gut, und wenn nichts anderes als ein Filter geht, weil alle Anfragen zu unscharf sind oder die Benutzer ihre Abfragen völlig frei selbst bauen können, ist es das Hilfsmittel der Wahl.
Herzlich,
Tom
Tom
Re: Filtern von rel. grossen Datenmengen
Hallo Wolfgang
In Deinem Fall kannst Du den Filter ja einfach lassen wie er ist und statt des "GO TOP" ein "SEEK" ausführen. Aber allenfalls wäre ein sporadisches PACK wie von Tom vorgeschlagen auch eine gute Idee.
Gruss
Marco
In Deinem Fall kannst Du den Filter ja einfach lassen wie er ist und statt des "GO TOP" ein "SEEK" ausführen. Aber allenfalls wäre ein sporadisches PACK wie von Tom vorgeschlagen auch eine gute Idee.
Gruss
Marco
- brandelh
- Foren-Moderator
- Beiträge: 15696
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: Filtern von rel. grossen Datenmengen
Ich habe mit dbScope() und Filter gute Erfahrungen gemacht, aber ab einer gewissen DBF Größe nudeln sich die alten Festplatten den Wolf ab.
Mit einer SSD wird es deutlich besser gehen !
Mit einer SSD wird es deutlich besser gehen !
Gruß
Hubert
Hubert
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9361
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 101 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: Filtern von rel. grossen Datenmengen
@Marco: Ein DbSeek() vor einem DbGoTop() mit gesetztem Filter nutzt überhaupt nichts. DbGoTop() bei aktivem Filter sagt: Gehe zum Anfang der Tabelle und skippe so lange, bis die Filterbedingung zutrifft. Und zwar ganz egal, wo Du vorher stehst und ob da der Filter zufällig zutrifft oder nicht. Bei einem aktiven Scope ist das anders. Da führt ein DbGoTop() immer dazu, dass zum Anfang der Datensatzmenge gesprungen wird, auf die die Scope-Bedingung zutrifft. Wenn zusätzlich ein Filter aktiv ist, wird von dort aus weitergeskippt, bis der erste Datensatz gefunden ist, auf den außerdem die Filterbedingung zutrifft.
Herzlich,
Tom
Tom
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Filtern von rel. grossen Datenmengen
Erst mal danke für die Tipps ...
Was ich nach wie vor nicht verstehe ist die Tatsache, daß vom Setzen des Filters "SET FILTERS TO ..." bis zum Beginn der "DO WHILE" Schleife schon ca. 10 Sek. vergehen. Die "DO While" Schleife selber ist in 3 Sek. fertig. Nach meinem Verständnis wird doch der Filter erst in der DO WHILE-Schleife wirksam und nicht durch GO TOP??
@JAN - die Eieruhr (oXbpSU) kriege ich auch nicht zum Laufen (siehe Code). Ist da was falsch oder muß ich noch was einbinden. Es tut sich jedenfalls nichts ..
Was ich nach wie vor nicht verstehe ist die Tatsache, daß vom Setzen des Filters "SET FILTERS TO ..." bis zum Beginn der "DO WHILE" Schleife schon ca. 10 Sek. vergehen. Die "DO While" Schleife selber ist in 3 Sek. fertig. Nach meinem Verständnis wird doch der Filter erst in der DO WHILE-Schleife wirksam und nicht durch GO TOP??
Code: Alles auswählen
IF !net_use2("vwrech_n4",.F.,5,"Y","n1")
MsgBox("Rechnungstabelle N1 gesperrt")
DBCLOSEALL()
RETURN(NIL)
ENDIF
SET DELETED ON
SET INDEX TO vwremat4, vwrenr4
SET FILTER TO n1->rech_jahr == aXbp[3]:getData() .AND. ALLTRIM(n1->rech_her)
MsgBox("286 - LISTE_220_AUSGABE() -> Filter: "+aXbp[6]:getData() ) // TEST
GO TOP
oXbpSU := XbpStatic():new(oDlg:drawingArea, ,{30,90}, {500,620} ) // Eieruhr
oXbpSU:caption := ""
oXbpSU:create()
oXbpSU:setPointer(, XBPSTATIC_SYSICON_WAIT, XBPWINDOW_POINTERTYPE_SYSPOINTER)
DO WHILE !EOF()
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9361
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 101 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: Filtern von rel. grossen Datenmengen
SET FILTER (oder DbSetFilter()) macht überhaupt nichts; es wird nur die Bedingung für die Workarea etabliert. Aber fast alle Navigationsfunktionen - DbGoTop(), DbSkip(), DbGoBottom() usw. - prüfen, ob eine Filterbedingung etabliert ist und evaluieren diese. Ein Filter wird erst mit dem ersten DbGoTop() wirksam. Wenn Du in Deine DO WHILE-Schleife kommst, bist Du schon innerhalb des Filters.
Herzlich,
Tom
Tom
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2825
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 96 Mal
- Danksagung erhalten: 13 Mal
Re: Filtern von rel. grossen Datenmengen
Hallo, Wolfgang -
wegen des Pointers: was gibt die Methode denn zurück? Wenn der Pointer geändert werden konnte, gibt sie .T. zurück - wenn .F. kommt, stimmt was nicht bei den Parametern, würde ich mal vermuten.
wegen des Pointers: was gibt die Methode denn zurück? Wenn der Pointer geändert werden konnte, gibt sie .T. zurück - wenn .F. kommt, stimmt was nicht bei den Parametern, würde ich mal vermuten.
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Filtern von rel. grossen Datenmengen
hm, ich traue mich ja kaum zu fragen ...
wie frage ich denn ab was eine Methode (speziell hier) zurück gibt?
wie frage ich denn ab was eine Methode (speziell hier) zurück gibt?
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2825
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 96 Mal
- Danksagung erhalten: 13 Mal
Re: Filtern von rel. grossen Datenmengen
lSuccess := oXbp:SetPointer(...)
So würde ich das versuchen. Eine Methode ist quasi eine Funktion, die an ein Objekt gebunden ist.
So würde ich das versuchen. Eine Methode ist quasi eine Funktion, die an ein Objekt gebunden ist.
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9361
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 101 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: Filtern von rel. grossen Datenmengen
Und die Rückgabewerte von Methoden, die zu Xbase++-Klassen gehören, stehen in der Doku.
Noch einmal, damit es ankommt. Man setzt einen Filter und es passiert überhaupt nichts - die Workarea merkt sich den Filter, mehr ist nicht. Der Datensatzzeiger wird nicht bewegt, selbst wenn der aktuelle Datensatz nicht der Filterbedingung entspricht. Aber einige Kommandos bzw. Funktionen zum Navigieren prüfen bei ihrer Ausführung, ob ein Filter aktiv ist: GO TOP (DbGoTop()), SKIP (DbSkip()), GO BOTTOM (DbGoBottom())). Und die bewegen den Satzzeiger immer wieder in die jeweilige Richtung, wenn sie auf Datensätze treffen, die nicht dem Filter entsprechen. DbGoTop() also lässt den Filter aktiv werden. Der Zeiger wird auf Satz 1 gesetzt und so lange inkrementiert, bis ein Datensatz kommt, der der Bedingung entspricht. Vorher passiert nichts.
Bei SEEK (DbSeek()) oder bei GO (DbGoto()) werden Filter nicht berücksichtigt. Mit DbGoto() können nicht der Filterbedingung und auch gelöschte Datensätze angesprungen werden. Und DbSeek() ignoriert Filter ebenfalls. SET SCOPE/DbSetScope() wiederum berücksichtigt Filter - und führt implizit ein DbGoTop() aus, anders als SET FILTER/DbSetFilter()!
Noch einmal, damit es ankommt. Man setzt einen Filter und es passiert überhaupt nichts - die Workarea merkt sich den Filter, mehr ist nicht. Der Datensatzzeiger wird nicht bewegt, selbst wenn der aktuelle Datensatz nicht der Filterbedingung entspricht. Aber einige Kommandos bzw. Funktionen zum Navigieren prüfen bei ihrer Ausführung, ob ein Filter aktiv ist: GO TOP (DbGoTop()), SKIP (DbSkip()), GO BOTTOM (DbGoBottom())). Und die bewegen den Satzzeiger immer wieder in die jeweilige Richtung, wenn sie auf Datensätze treffen, die nicht dem Filter entsprechen. DbGoTop() also lässt den Filter aktiv werden. Der Zeiger wird auf Satz 1 gesetzt und so lange inkrementiert, bis ein Datensatz kommt, der der Bedingung entspricht. Vorher passiert nichts.
Bei SEEK (DbSeek()) oder bei GO (DbGoto()) werden Filter nicht berücksichtigt. Mit DbGoto() können nicht der Filterbedingung und auch gelöschte Datensätze angesprungen werden. Und DbSeek() ignoriert Filter ebenfalls. SET SCOPE/DbSetScope() wiederum berücksichtigt Filter - und führt implizit ein DbGoTop() aus, anders als SET FILTER/DbSetFilter()!
Herzlich,
Tom
Tom
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Filtern von rel. grossen Datenmengen
Tom
heißt das, dass die eigentliche Selektion schon vor "Do While" und nach "GO TOP" stattfindet?
Übrigens, bei der Tabelle sind keine gelöschten Sätze vorhanden..
heißt das, dass die eigentliche Selektion schon vor "Do While" und nach "GO TOP" stattfindet?
Übrigens, bei der Tabelle sind keine gelöschten Sätze vorhanden..
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9361
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 101 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: Filtern von rel. grossen Datenmengen
Das "GO TOP" ist die erste Zeile, die etwas bezogen auf den Filter macht. Statt nur zum ersten Satz in der Tabelle (Ordinalposition) zu gehen, wird dort hingegangen und dann geprüft, ob der Datensatz der Filterbedingung genügt. Und dann wird so lange DbSkip(1) (oder SKIP) ausgeführt, bis ein Datensatz gefunden wird, auf den der Filter zutrifft. SET FILTER macht selbst nichts, was den Satzzeiger betrifft. Siehe Aufzählung von weiter oben. Wenn Du ein SET FILTER TO mit einer komplexen Textsuche auf einer Tabelle machst, die Milliarden von Datensätzen enthält, und erst der letzte Datensatz entspricht dem Filter, dann löst SET FILTER TO selbst trotzdem überhaupt keine Verzögerung aus. Erst DbGoTop() bewirkt das.
Herzlich,
Tom
Tom
Re: Filtern von rel. grossen Datenmengen
@Tom
Deshalb meinte ich SEEK statt GO TOP. So wie es aussieht werden ja z.B. alle Rechnungen eines Jahres gesucht. Und falls der Index auf das Datum bereits existiert wäre ein SEEK (dbSeek()) eben die einfachste Lösung. Ich gebe Dir aber Recht, dass unter Umständen die Scope-Variante schneller und eleganter wäre (dazu müsste man aber wissen, ob es unterschiedliche Kriterien für den Filter gibt oder immer nur einen Datums-Bereich eingegrenzt wird).
Deshalb meinte ich SEEK statt GO TOP. So wie es aussieht werden ja z.B. alle Rechnungen eines Jahres gesucht. Und falls der Index auf das Datum bereits existiert wäre ein SEEK (dbSeek()) eben die einfachste Lösung. Ich gebe Dir aber Recht, dass unter Umständen die Scope-Variante schneller und eleganter wäre (dazu müsste man aber wissen, ob es unterschiedliche Kriterien für den Filter gibt oder immer nur einen Datums-Bereich eingegrenzt wird).
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Filtern von rel. grossen Datenmengen
@scarmo
Es gibt mehrere Varianten des Filters. Das Jahr war nur ein Beispiel. Es gibt z.B. den Filter Rechnungsjahr+Rechnungsart+user usw.
@Tom
Danke für die Erklärung. Ich glaube ich habe es jetzt verstanden.
@Georg
Die Methode lSuccess := oXbp:SetPointer(...) gibt .T. zurück.
Ich versuche mal DBSetScope().
Nochmal danke an alle ...
Es gibt mehrere Varianten des Filters. Das Jahr war nur ein Beispiel. Es gibt z.B. den Filter Rechnungsjahr+Rechnungsart+user usw.
@Tom
Danke für die Erklärung. Ich glaube ich habe es jetzt verstanden.
@Georg
Die Methode lSuccess := oXbp:SetPointer(...) gibt .T. zurück.
Ich versuche mal DBSetScope().
Nochmal danke an alle ...
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Filtern von rel. grossen Datenmengen
nochmal setpointer ...
Funktioniert doch!!! Es ist bei WIN10 nur keine Eieruhr mehr sondern ein Kringel
Funktioniert doch!!! Es ist bei WIN10 nur keine Eieruhr mehr sondern ein Kringel
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Filtern von rel. grossen Datenmengen
interessant was hier alles geschrieben wird.
@Wolfgang : "wo" führst du SET FILTER durch
wenn ich einen FILTER in DBU (Xbase++ Version) setze steht er unter v1.9x auf dem ersten "Treffer" OHNE ein GOTOP
@Wolfgang : "wo" führst du SET FILTER durch
wenn ich einen FILTER in DBU (Xbase++ Version) setze steht er unter v1.9x auf dem ersten "Treffer" OHNE ein GOTOP
gruss by OHR
Jimmy
Jimmy
- HaPe
- 1000 working lines a day
- Beiträge: 996
- Registriert: So, 15. Nov 2015 17:44
- Wohnort: 71665 Vaihingen-Enz
- Hat sich bedankt: 17 Mal
- Danksagung erhalten: 15 Mal
Re: Filtern von rel. grossen Datenmengen
Hallo Jimmy !
Nachdem eine Filterbedingung mit SET FILTER definiert worden ist, muß der Datensatzzeiger mindestens einmal bewegt werden, um sicherzustellen, daß der aktuelle Datensatz der Filterbedingung entspricht. ...
Und in der 2.0er Hilfe das Ganze in Englisch.
Das ist genau das was Tom oben schon gesagt hat; und das ist Standard bei den xbase-Sprachen wie Clipper, dBase, Xbase++, Visual Foxpro, ...
In der 1.9er Hilfe steht zu SET FILTER:wenn ich einen FILTER in DBU (Xbase++ Version) setze steht er unter v1.9x auf dem ersten "Treffer" OHNE ein GOTOP
Nachdem eine Filterbedingung mit SET FILTER definiert worden ist, muß der Datensatzzeiger mindestens einmal bewegt werden, um sicherzustellen, daß der aktuelle Datensatz der Filterbedingung entspricht. ...
Und in der 2.0er Hilfe das Ganze in Englisch.
Das ist genau das was Tom oben schon gesagt hat; und das ist Standard bei den xbase-Sprachen wie Clipper, dBase, Xbase++, Visual Foxpro, ...
--
Hans-Peter
Hans-Peter