Alternative zu SET FILTER TO ? [ERLEDIGT]

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Benutzeravatar
denjo303
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 48
Registriert: Mo, 18. Jul 2011 18:10

Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von denjo303 »

hoi leute...

wie der titel schon beschreibt suche ich nach einer alternative zu "SET FILTER TO".

ich habe datenbanken vom kunden die mehrere 10000 datensätze haben und da ist diese methode einfach zu langsam.

gibts da was sportlicheres?
Zuletzt geändert von denjo303 am Di, 03. Jan 2012 8:38, insgesamt 1-mal geändert.
Über 4.000.000 Menschen hören Hiphop. Schreib dich nicht ab, lern reden und gehen.
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14655
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ?

Beitrag von Jan »

Klar. Scopes. Super schnell, aber auf das zu "filternde" Feld muß ein Index bestehen.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ?

Beitrag von Tom »

Es kommt darauf an, wonach gesucht werden soll. Bei eindeutigen Kriterien ist natürlich eine Indexsuche zu bevorzugen, die aber gewissen Einschränkungen unterliegt. Wenn man ein Suchkriterium konkret bzw. vollständig kennt (etwa eine Nummer) und es gibt einen Index auf diese Nummer, kann DbSeek() (oder ein Scope) benutzt werden. Teilsuche nach alphanumerischen Daten (Kundennamen - man sucht "Müller" und findet u.a. "Müller-Lüdenscheid" - "Lüdenscheid" findet allerdings diesen Datensatz nicht) ist auch weitgehend unproblematisch. Seit 1.9/SL1 gibt es OrdWildSeek(), das auch Wildcards (? und *) zulässt (hiermit ließe sich "Müller-Lüdenscheid" mit dem Suchkriterium "*Lüdenscheid" finden), aber die "Ergebnismenge" ist mit Vorsicht zu genießen, denn der nächste Treffer ist nicht notwendigerweise auch der nächste Datensatz - zwischen dem ersten und dem zweiten Treffer können nicht-zutreffende Datensätze liegen. Indexe können auch komplexe Ausdrücke, die Ergebnisse von UDFs und konkatinierte Daten enthalten, etwa Str(Kundennr)+Str(Artikelnr), was eine Suche nach der Kundennummer und eine Suche nach Kunden- und Artikelnummer erlauben würde (aber nicht nach Artikelnr!).

Schwierig wird es bei Volltextsuchen in nicht-indexierten Feldern, also dem klassischen Einsatzgebiet von DbSetFilter() bzw. DbLocate() (die Funktionsweise entspricht sich grundsätzlich). Hierfür gibt es aber Algorithmen, die schneller als Filter sind. Wenn ich mich recht erinnere, gab es sogar mal was im ASCN, aber dort finde ich derzeit nichts. Es gibt allerdings einen relativ simplen Trick, um Filter dramatisch zu beschleunigen, indem man nämlich die komplette Tabelle (bzw. die auszuwertenden Felder) in ein Array einliest (DO WHILE !Eof(); Aadd(...); ENDDO) und die Volltextsuche dann auf das Array anwendet. Für die anschließende Datensatzanzeige verwendet man dann nur noch die Datensatznummer aus dem Array.
Herzlich,
Tom
Benutzeravatar
denjo303
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 48
Registriert: Mo, 18. Jul 2011 18:10

Re: Alternative zu SET FILTER TO ?

Beitrag von denjo303 »

ah ok,

es gibt also sehr viele alternativen... je nach dem wie man suchen / filtern will.

danke danke... das hat mir sehr geholfen =D>
Über 4.000.000 Menschen hören Hiphop. Schreib dich nicht ab, lern reden und gehen.
Benutzeravatar
azzo
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 483
Registriert: So, 28. Mär 2010 19:21
Danksagung erhalten: 11 Mal

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von azzo »

Volltextsuche in dbf-Dateien.
mfg
Otto

Code: Alles auswählen


function SearchFile( suchbeg )
   local aGefunden := {}
   local nLocation, cData
   local nOffset := 0
   local cDBF    := "test.dbf" 
   local nPos    := 0
   *----------------------------------------------------------
  
   suchbeg := ALLTRIM(Upper(suchbeg))
   cData   := Upper(MemoRead( cDBF ))
   if Len(cData ) < 1
      MsgInfo("Not Data to Search","File Error")
      Return Nil
   endif
   nOffset := 0
   do while .t.
           nPos := INT( AT( suchbeg, cData, nOffset ))
                nLocation := INT( ( nPos - Header() ) / RecSize() ) + 1
                nOffset   := Header() + nLocation * RecSize() //+ RecSize()

      if nPos > 0 .and. nPos <  Header()
      else
              if nLocation < 1
                 Exit
              else
                 select test
                 goto nLocation
                 if DELETED() = .F.
                        aAdd( aGefunden, getrec() )
                           endif
              endif

                endif

   enddo

Return Nil
//----------------------------------------------------------------------------//


Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2126
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 75 Mal

Re: Alternative zu SET FILTER TO ?

Beitrag von Werner_Bayern »

Tom hat geschrieben:Es gibt allerdings einen relativ simplen Trick, um Filter dramatisch zu beschleunigen, indem man nämlich die komplette Tabelle (bzw. die auszuwertenden Felder) in ein Array einliest (DO WHILE !Eof(); Aadd(...); ENDDO) und die Volltextsuche dann auf das Array anwendet. Für die anschließende Datensatzanzeige verwendet man dann nur noch die Datensatznummer aus dem Array.
Servus Tom,

wie meinst Du das? Für´s aadd() schon auf die Bedingung prüfen, sodaß wenige aadd´s ausgeführt werden und man sich dann die Suche im Array erspart, oder erstmal wirklich alles in ein Array (vorher entsprechend dimensioniert) schaufeln und dann mittels ascan? Wäre dann aber speicherkritisch je nach Anzahl der Sätze und Größe der Felder (inkl. evtl. Memo-Felder).

Danke.
es grüßt

Werner

<when the music is over, turn off the lights!>
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ?

Beitrag von UliTs »

Tom hat geschrieben:Es gibt allerdings einen relativ simplen Trick, um Filter dramatisch zu beschleunigen, indem man nämlich die komplette Tabelle (bzw. die auszuwertenden Felder) in ein Array einliest (DO WHILE !Eof(); Aadd(...); ENDDO) und die Volltextsuche dann auf das Array anwendet. Für die anschließende Datensatzanzeige verwendet man dann nur noch die Datensatznummer aus dem Array.
Den Trick finde ich aber alles andere als "simpel" :D .
Mehrere 10.000 Datensätze einlesen dauert doch auch schon einige 10tel-Sekunden :? .

Es gibt noch eine Alternative: Einsatz des Advantage Database Server (ADS). Das gehen auch Filter sehr schnell und bei Einsatz von FullTextSearch-Indizes sogar rasend schnell, auch beim Suchen in Memofeldern! Wenn man die Professional-Version von xBase hat, ist der notwendige Treiber kostenlos dabei und wenn einem Local-Zugriff reicht, ist der ADS kostenlos.

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von Tom »

Hallo, Uli.

Wenn Du eine Tabelle mit beispielsweise 10.000 Datensätzen hast, auf die Du einen komplexen Filter anwendest, der mit Instring-Suche und allem möglichen Pipapo arbeitet, und der physikalisch oder logisch letzte Datensatz ist der einzige, der der Filterbedingung entspricht, wird diese 10.000 Mal evaluiert, bis der fragliche Datensatz gefunden wurde, zuerst beim DbGoTop() und dann bei jedem DbSkip(). Jeder Datensatz wird gelesen, geprüft, dann geht's zum nächsten. 10.000 Datensätze sind noch recht wenig. Lass es zehn- oder hundert Mal so viele sein. Je nach Filter und Hardware kann das ordentlich dauern, die eigentliche Bremse aber ist die Filterbedingung, die nach jedem Lesevorgang ausgewertet wird. Wenn ich aber eine Tabelle mit 10.000 oder 100.000 Datensätzen einfach "straight ahead" durchwandere und nur die Felder (nebst RecNo()), die ich für die Filterbedingung benötige, in ein Array umpacke, bin ich, was den eigentlichen Lesevorgang anbetrifft, deutlich schneller. Den Filter (der dann keiner mehr ist) wende ich anschließend auf das Array an, etwa mit aScan(), möglicherweise auch einfach in einer simplen Iteration. Von hieraus kann ich dann bequem zu den Datensätzen navigieren, die der Bedingung entsprechen. Ich sage nicht, dass dies die eleganteste Lösung ist, und sie ist definitiv langsamer als ein optimierter Filter mit ADS, aber man kann auf diesem Weg einiges herausholen. Auf jeden Fall schneller ist dieser Weg, wenn man auf einer gefilterten Datenbank navigiert, etwa in einem Browse, denn standardmäßig evaluiert die Engine den Filter immer wieder, bei jeder Navigation, also auch, wenn man sich auf Datensätze bewegt, von denen bereits bekannt ist, dass sie dem Filter genügen oder nicht. Wenn ich die Navigation (etwa über die Navigationsblöcke des Browses) so umstricke, dass sie auf Basis des Arrays arbeitet, spare ich immense Zeit. Genau dieses System wendet meiner Meinung nach übrigens die Engine an, wenn mit SET SMARTFILTER ON gearbeitet wird, eine Einstellung, die mit Xbase++ 1.90 kam, und die wir - wie SET RUSHMORE - allesamt wieder abschalten sollten, weil damit unvorhersehbare Probleme einhergingen. Benutzt das jemand? Ich tue es, und der Unterschied ist bemerkenswert!

Viel sinnvoller ist natürlich, Indexe so zu konstruieren, dass man mit der Indexsuche arbeiten kann, z.B. auch mit OrdWildSeek(). Oder mit einer kombinierten Suche, vorrangig über einen Index (oder mehrere) und anschließend/parallel unter Auswertung der Datensätze, die wenigstens der Indexbedingung entsprachen.
Herzlich,
Tom
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von UliTs »

Hallo Tom,

wenn man auf gefilterten Datensätzen mit Local-Zugriff navigiert, stimme ich Dir voll zu. Das kostet ordentlich Zeit.
Ganz habe ich Deinen Hinweis bezüglich
...Genau dieses System wendet meiner Meinung nach übrigens die Engine an, wenn mit SET SMARTFILTER ON gearbeitet wird, eine Einstellung, die mit Xbase++ 1.90 kam, und die wir - wie SET RUSHMORE - allesamt wieder abschalten sollten, weil damit unvorhersehbare Probleme einhergingen. Benutzt das jemand? Ich tue es, und der Unterschied ist bemerkenswert!
nicht verstanden. Einerseits schreibst Du "alles wieder abschalten" andererseits schreibst Du, Du benutzt es und der Unterschied ist bemerkenswert?
-
Ich habe mich damit bisher nicht beschäftigt. Ich vermute, da ich den ADS benutze, ist es für mich unwesentlich?

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von Tom »

Hallo, Uli.

Wenn Deine Filterausdrücke tatsächlich von der ADS und nicht lokal evaluiert werden (das kannst Du durch Prüfung der ADS-Fehlerdatei feststellen), bringt Dir der Smartfilter tatsächlich nichts (er ist übrigens mit Xbase++ 1.70 eingeführt worden). Ansonsten bin ich der Meinung, dass die Systematik inzwischen einwandfrei funktioniert. Wenn der Smartfilter an ist, sammelt die Engine die Datensätze ein, die dem Filter genügen, also merkt sich deren Daten beim ersten Kontakt. Wird dann ein solcher Datensatz abermals angesprungen, muss der Filter nicht noch einmal evaluiert werden, der der Datensatz ist in der Sammlung. Etwas ähnliches habe ich auch selbst konstruiert, bis ich gemerkt habe, dass die Systematik offenbar funktioniert. Es gibt auch keine offenen PDRs zum Smartfilter.

Verwendet irgendwer den "Rushmore-Optimierer"? Das war doch letztlich eine ähnliche Geschichte. Es hieß, das sollte besser abgeschaltet werden, aber eine Freigabenachricht kam nie. Offene PDRs gibt es aber hierfür auch nicht.
Herzlich,
Tom
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von UliTs »

Hallo Tom,

vielen Dank für Deine Info. Ich setze ausschließlich Filter ein, die vom ADS ausgewertet werden können :-) . Wobei ich immer weniger mit DbUseArea() arbeite, so dass es gar nicht anders geht...
Der Hinweis mit der ADS-Fehlerdatei ist aber sehr interessant. Die schaue ich mich sicher viel zu selten an. Wer weiss, vielleicht habe ich den ein- oder anderen Filter ja falsch umgesetzt :shock:

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2126
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 75 Mal

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von Werner_Bayern »

Tom hat geschrieben:Verwendet irgendwer den "Rushmore-Optimierer"?
Offensichtlich fast jeder, Zitat aus der Referenz:
Standardmäßig sind SET OPTIMIZE, SET SMARTFILTER und SET RUSHMORE auf ON gesetzt, d.h. der Datenbank-Kernel von Xbase++ wendet die verschiedenen Optimierungstechniken aufgrund seiner internen Logik an.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von AUGE_OHR »

Werner_Bayern hat geschrieben:Offensichtlich fast jeder, Zitat aus der Referenz:
Standardmäßig sind SET OPTIMIZE, SET SMARTFILTER und SET RUSHMORE auf ON gesetzt, d.h. der Datenbank-Kernel von Xbase++ wendet die verschiedenen Optimierungstechniken aufgrund seiner internen Logik an.
man sollte die "Optimierungen" aber NICHT mit DBFNTX verwenden wenn gleichzeitig Cl*pper darauf zugreifen soll !
grob gesagt : alles was Cl*pper nicht kann MUSS man in Xbase++ "ausschalten" wenn man gleichzeitig mit "von" Cl*pper angelegten DBF arbeiten will.
gruss by OHR
Jimmy
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von Tom »

Hallo, Jimmy.

Mit Verlaub, Blödsinn. Smartfilter und Rushmore sind Optimierungen, die mit Datenstrukturen, Locking und ähnlichem nichts zu tun haben. Es handelt sich um Mechanismen, die die Datenauswertung beschleunigen. Smartfilter etwa sammelt einfach für eine Workarea, auf der ein Filter sitzt, bei Navigation die Datensätze ein, die dem Filter entsprechen, und verhindert damit, dass der Filter abermals evaluiert werden muss, wenn ein Datensatz zum zweiten Mal angesprochen wird. Strukturell und im Hinblick auf alle Low-Level-Systematiken ist das völlig unerheblich; es entspräche der Systematik, die ich weiter oben vorgeschlagen habe: Man merkt sich einfach in einem Array die Datensätze, die einem Filter genügen. Ob da eine Clipper-App parallel läuft oder nicht ist so unerheblich wie ein Magnetsturm auf der Venus.
Herzlich,
Tom
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von UliTs »

Tom hat geschrieben:Hallo, Jimmy.
Mit Verlaub, Blödsinn...
Hallo Tom,
im Prinzip hast du Recht, glaube ich :-) .
Aber für den Fall, dass sich die gefilterten Daten (z.B. durch einen anderen Nutzer oder Thread) ändern, könnte es da schon Unterschiede geben.
Nämlich dann, wenn dem Programm bzw. Thread mit den gefilterten Daten automatisch mitgeteilt wird, dass sich Datensatz X geändert hat und deshalb der Filter für diesen Datensatz erneut ausgewertet werden muß.
Ich vermute aber, dass kann auch xBase bei lokalem Zugriff nicht, oder?

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von Tom »

Hallo, Uli.

Weil der Smartfilter problematisch werden kann, wenn sich Datensätze geändert haben, gibt es die Funktion DbRefresh(). Diese setzt den Smartfilter zurück, so dass die Evaluierung des Filters von Neuem beginnt.

All das - auch OPTIMIZE und RUSHMORE - findet in einer Schicht statt, die mit der Datenhaltung selbst überhaupt nichts zu tun hat. Wenn man tatsächlich noch im konkurrierenden Betrieb arbeitet, muss man auf andere Dinge achten - die Einstellungen für die DBE, Locking-Modi, Zeichensätze und ähnliches, eben Dinge, die den konkurrierenden Zugriff und die Datenhaltung selbst betreffen. Die Optimierungsmechanismen setzen ganz woanders an und beeinflussen das überhaupt nicht. Man kann solche Techniken auch selbst implementieren, ohne Probleme für den gleichzeitigen Zugriff zu erzeugen. Siehe Beispiel weiter oben.
Herzlich,
Tom
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von UliTs »

Tom hat geschrieben:..
Weil der Smartfilter problematisch werden kann, wenn sich Datensätze geändert haben, gibt es die Funktion DbRefresh(). Diese setzt den Smartfilter zurück, so dass die Evaluierung des Filters von Neuem beginnt.
All das - auch OPTIMIZE und RUSHMORE - findet in einer Schicht statt, die mit der Datenhaltung selbst überhaupt nichts zu tun hat.
...
Also nach der Dokumentation muß man DbRefresh() manuell aufrufen. Dies geschieht danach nicht automatisch durch "äußere" Einflüsse. Ich schließe daraus, dass xBase dies schlicht und einfach nicht kann ...
Wer arbeitet NICHT im konkurrierenden Betrieb? Ich habe keine mit xBase geschriebenen Einzelplatzanwendungen.

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von Tom »

Hallo, Uli.

Klar kann Xbase++ das - indem es ohne Smartfilter betrieben wird. Dann wird für jeden Datensatz geprüft, ob er der Bedingung entspricht oder nicht, und eben auch für den Fall einer Änderung. :wink:

Das ist eine Technik, die man dazu benutzen kann, eine Anwendung zu beschleunigen, aber es ist natürlich eine Frage des Designs, wie und ob man das tut. Wenn man mit einem SQL-Cursor (Current Record Set) arbeitet, hat man einen Snapshot aus der Datenbank zum Zeitpunkt der Abfrage. Das ist ein wesentlicher "Trick" bei SQL, viele Online-Anwendungen wären erschreckend lahm, würden sie nicht so arbeiten. Während man also den Cursor sieht, kann die Datenbank schon längst auf einem völlig anderen Stand sein. Man muss das in der Anwendung entsprechend reflektieren. Man kann auch mit einem Live-Cursor arbeiten, aber dann verschenkt man den Performance-Vorteil.

Ich nutze Smartfilter in Bereichen, in denen ich relativ sicher sein kann, dass sich die Ergebnismenge nicht zwischenzeitlich geändert hat - oder in denen unerheblich ist, ob das geschehen ist, weil Benutzer tatsächlich einen Snapshot sehen woll(t)en. Von Zeit zu Zeit wird ein DbRefresh() ausgelöst, etwa, wenn ich sehe, dass mit den Tabellen etwas passiert ist. Zusätzlich kann das manuell ("Aktualisieren") erfolgen. Aber ich benutze es nicht überall. Und ich arbeite grundsätzlich recht wenig mit Filtern.

SET OPTIMIZE und SET RUSHMORE sind andere Techniken, die von derlei übrigens nicht beeinflusst werden.

Edit: Es gibt zusätzliche Möglichkeiten, auf Tabellenänderungen zu reagieren, etwa DbRegisterClient(). Damit kann ein Browse, das einen Smartfilter verwendet, auch selbsttätig das nötige DbRefresh() auslösen.
Herzlich,
Tom
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von UliTs »

Tom hat geschrieben:Hallo, Uli.
Klar kann Xbase++ das - indem es ohne Smartfilter betrieben wird. Dann wird für jeden Datensatz geprüft, ob er der Bedingung entspricht oder nicht, und eben auch für den Fall einer Änderung. :wink:
Das ist jetzt aber Quatsch ;-) Die Frage war ja, kann es das auch mit eingeschaltetetem Smartfilter 8) .
Tom hat geschrieben:Wenn man mit einem SQL-Cursor (Current Record Set) arbeitet, hat man einen Snapshot aus der Datenbank zum Zeitpunkt der Abfrage. Das ist ein wesentlicher "Trick" bei SQL, viele Online-Anwendungen wären erschreckend lahm, würden sie nicht so arbeiten. Während man also den Cursor sieht, kann die Datenbank schon längst auf einem völlig anderen Stand sein. Man muss das in der Anwendung entsprechend reflektieren. Man kann auch mit einem Live-Cursor arbeiten, aber dann verschenkt man den Performance-Vorteil.
Nach Aussage von Extended Systems (bzw. SAP :-) ) sind bei geschicktem Einsatz von Live-Cursorn mit dem Advantage Database Server diese drastisch schneller als Static-Cursor. Dies ist auch meine Erfahrung! Wenn ich einen Browser über einen Live-Cursor habe, braucht die Darstellung nur wenige Zehntelsekunden unabhängig von der Anzahl der Datensätze. Beim Einsatz eines Static-Cursor dauert das Gleiche selbst bei nur wenigen 10000 Datensätzen schon einige Sekunden.
Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von Tom »

Hallo, Uli.

Es geht um Online-Anwendungen, das schrub ich ja auch. Wenn Du irgendein Buchungssystem aufrufst, siehst Du den Reservierungsstand zum Zeitpunkt des Abrufs. Du hast in der Regel keine Garantie, dass z.B. der ausgewählte Sitzplatz im Kino auch noch verfügbar ist, wenn Du den Reservierungsvorgang beendest. Das wird üblicherweise erst im Anschluss geprüft. Auch Amazon zeigt Dir beispielsweise an, dass "Noch 3 Exemplare auf Lager" sind, wenn Du eine Produktseite siehst. Das ist aber keine Garantie dafür, dass Du eines dieser drei Exemplare bekommst, wenn Du auf "Bestellen" klickst. Gut möglich, dass sie inzwischen weg sind.

Ja, Live-Cursor können schneller sein. Aber sie erzeugen dann auch Last und Traffic. :wink:
Herzlich,
Tom
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von UliTs »

Hallo Tom,

das mit den Online-Anwendungen war mir entgangen. Wobei meines Erachtens auch da intelligente Live-Aktualisierungen elegant wären und zumindest in meinem Kopf theoretisch ohne viel Traffic möglich sein sollten, entsprechende Softwaremöglichkeiten vorausgesetzt :shock: :D .
Weswegen sollen denn Live-Cursor Last und Traffic erzeugen :?: Im Gegenteil, ich habe die Erfahrung gemacht, dass der Server dadurch drastisch entlastet wird (was die Last angeht). Beim Traffic könnte ich mir schon vorstellen, dass bei Static Cursorn die Daten auf der Workstation automatisch problemlos gepuffert werden könnten und so Vorteile gegenüber Live Cursorn sind.

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von Tom »

Hallo, Uli.

Ein Static Cursor ist ein Snapshot, ein Live Cursor ist eine bewegliche Ergebnismenge. Dass da Lasten und Traffic entstehen, ist unvermeidbar. Beides hat Vor- und Nachteile. Beides kann man optimieren. Aber eine Ergebnismenge, die ständig aktualisiert werden muss, ist ohne Last und Traffic unmöglich. Oder wie stellst Du Dir das vor?
Herzlich,
Tom
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von UliTs »

Tom hat geschrieben:Hallo, Uli.

Ein Static Cursor ist ein Snapshot, ein Live Cursor ist eine bewegliche Ergebnismenge. Dass da Lasten und Traffic entstehen, ist unvermeidbar. Beides hat Vor- und Nachteile. Beides kann man optimieren. Aber eine Ergebnismenge, die ständig aktualisiert werden muss, ist ohne Last und Traffic unmöglich. Oder wie stellst Du Dir das vor?
Hallo Tom,
bei einem Snapshot müssen die Daten zum Zeitpunkt des Snapshots erhalten bleiben. Wenn sich also Datensatz 123456 ändert, muß selbiger anschließend doppelt vorhanden sein a) zum Zeitpunkt des Snapshot b) zum aktuellen Zeitpunkt. Selbst wenn man sich zunächst nur die Datensätze 1-20 anschaut, muß für den Fall der Fälle der Datensatz 123456 zum Zeitpunkt des Snapshot gespeichert bleiben, so dass eine erhöhte Serverlast entsteht.
Beim Live Cursor spielt das keine Rolle, da ja immer nur die aktuellen Werte der Datensätze verlangt werden. Eine erhöhte Last und Traffic beim Live Cursor entsteht nur dann, wenn man die Datensätze, die man sich gerade anschaut (z.B. 1-20) immer wieder aktualisiert.

Ich habe den Eindruck, dass Static Cursor bei kleinen Ergebnismengen (<1000 Datensätze) schnell genug sind, bei großen Ergebnismengen jedoch der Live Cursor große Vorteile hat.

Bei der DevCon wird ja auch Joachim Dürr als Sprecher sein. Das wird bestimmt hochinteressant. Und ihn kann man am Besten auch noch einmal nach Vor-/Nachteilen zu Live- und Static-Cursor(n) (mit oder ohne n?) fragen.

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von Markus Walter »

Hallo Uli,
hallo Tom,

wie schnell Live- oder Static-Cursor sind, bzw. wieviel Last diese erzeugen, hängt natürlich auch davon ab, was an damit tut. Wenn ich (warum auch immer) einen "großen" (viele Datensätze) Live-Cursor erzeuge und diesen dann durchlaufe, um irgendwelche Auswertungen zu rechnen, führt das zu einer größeren Serverlast, als wenn ich einen großen Live-Cursor in einem Browse anzeige und der Anwender den dritten Datensatz anwählt und das Browse beendet. Der Static-Cursor hätte im ersten Fall sicher Vorteile (zumindest für den Sever).
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Alternative zu SET FILTER TO ? [ERLEDIGT]

Beitrag von Tom »

Es hängt auch vom Server ab. Microsoft SQL erzeugt beispielsweise für jeden Cursor eine temporäre Tabelle, die auch erst wieder gelöscht wird, wenn die SQL-Sitzung endet.

Ausgangspunkt der Diskussion aber war, dass es Smartfilter erlaubt, bei aktivem Filter die Navigation deutlich zu beschleunigen, weil der Filter dann nur noch einmal für jeden Datensatz evaluiert wird. Ob man nun noch zusätzlich dafür sorgen muss, dass auf eventuelle Aktualisierungen der Tabelle per DbRefresh() reagiert wird, hängt schlicht davon ab, ob es nötig ist. Wenn ich beispielsweise eine umfangreiche Datamining-Auswertung über eine Tabelle anzeige, für die Filter gesetzt werden können, kann ich ohne weitere Mechanismen mit Smartfilter arbeiten. Wenn ich ähnliches für eine Kundentabelle zulasse, möchte ich möglicherweise, dass sich der Filter auch aktuell(er) verhält. Dann muss ich mit zusätzlichen Funktionalitäten dafür sorgen, dass etwaige Änderungen in der Tabelle reflektiert werden, simpel etwa durch ihre Metadaten (Timestamp der letzten Änderung). Übrigens löst DbRefresh() nicht nur das Zurücksetzen des Smartfilter-Counters aus, sondern löscht auch alle Puffer der Workarea. :!:
Herzlich,
Tom
Antworten