View Full Version : positionieren im Resultset
Hallo,
ich habe folgenden Zustand:
Ich habe eine Datei die meherer Millionen Sätze beinhaltet auf der ich ein ResultSet aufbaue, der Cursor ist 'dynamic scroll' deklariert und nach einer 'Vorgangsnummer' sortiert mit diesem kann ich auch ohne Probleme in meinem Programm blättern per 'Fetch'.
Nun ist mein Problem, dass Positionieren im ResultSet, da es gute 15-20 sek dauert bis ich bei dem ensprechenden Satz ankommen
z.b 3700000.
Meine derzeitige Lösung ist alle vorgehenden
Sätze per Count zu zählen und dann mit
'Fetch before' an den Anfang zu gehen und von dort per 'Fetch Relative' auf den ensprechenden Satz.
Danke im vorraus
Ben
... kein schlechter Wert 20 sec. für 3,7 Millionen Sätze Index sequentiell zu durchsuchen - works as designed!
D*B
, der sich wundert wofür das gut sein soll
Als Zusatz Info
Das Programm baut eine Liste von 12 Sätzen pro Seite auf ich kann mit 'Bild auf' und 'Bild ab' je eine Seite auf und abblättern(also je 12 Zeilen vor oder zurück) auf jeden Satz im aktuellen Bild kann ich mit einer Auswahl die Sätze ändern oder löschen.
Wenn ich nun zu einem bestimmten Satz möchte muss ich neu Positionieren, da braucht es halt was länger(gibt viele ungeduldige dort draußen die nicht 15 sek warten wollen), daher war meine Frage, ob es einen schnelleren weg gibt zu Positionieren.
So dass ich nach der Positionierung normal weiter blättern kann im Programm
... da gibt es mehrere Möglichkeiten
- die bereits gelesenen Daten im Subfile merken
- die bereits gelesenen Daten im Programm merken
- wenn ein Sortierfeld da ist, den Cursor neu aufsetzen und öffnen
- AS400 typisch lässt man auch den Cursor offen und positioniert dann relativ zur letzten Position
... je nach Programmiersprache kommt dann noch einiges dazu...
D*B
Klabautermann
25-08-11, 09:00
Hallo,
wir haben ein ähnliches Problem.
Wir haben eine Datei in der 5 mio Datensätze stehen, welche angezeigt werden sollen.
Angezeigt werden diese Sätze über ein Subfile Steuerungsprogramm, welches an mein Programm Kennzeichen zur Steuerung(READ/READP/etc.) übergibt. Das Steuerungsprogramm erwartet immer bestimmte Parameter für die weitere Verarbeitung(Auswahlen) und eine aufbereitete Zeile, welche angezeigt wird.
Mein Programm ist ein SQLRPG, welches sich ein Resultset der Datei holt.
Wenn ich nun auf einem bestimmten Satz positionieren möchte, also alle Sätze ab diesem Satz lesen möchte, muss ich im das ResultSet lesen, bis der entsprechende Satz gefunden wurde.
Gibt es eine Möglichkeit im ResultSet absolut zu Positionieren?
@BenderD: Deine Vorschläge habe ich ebenfalls versucht.
- die bereits gelesenen Daten im Subfile merken
Ist keine option. auch hier kann ich nicht ab einem bestimmten satz positionieren. Außerdem kann ich maximal 9999 Sätze in das Subfile schreiben.
- die bereits gelesenen Daten im Programm merken
Könnte ich machen. Aber das problem ist, dass ich nicht weiß wie ich mein Array Dimensionieren soll. Mit einem Dynamischen Array zu arbeiten wäre eine option. Allerdings muss ich dann wieder mit einer Schleife mein Array durcharbeiten und prüfen, ob der Wert mit dem übergebenen übereinstimmt.
-wenn ein Sortierfeld da ist, den Cursor neu aufsetzen und öffnen
Ein Sortierfeld ist da. Wenn ich den Cursor aber ab der Position aufsetze, kann ich doch nicht zurückblättern.
- AS400 typisch lässt man auch den Cursor offen und positioniert dann relativ zur letzten Position
Den Cursor lasse ich offen. Allerdings müsste ich dann ertesten, welcher weg der kürzere ist. Ob vom Anfang/Ende/aktueller position. Auch das ist meiner Meinung nach nicht sauber.Vielen Dank für eure hilfe.
!!!Anmerkung für die RLA Liebhaber!!!
die bei weitem schnellste Variante ist Array mit DIM(999) anlegen und mit SQL per Blockfetch mit statischem Cursor auf einen ratsch füllen und dann alles Speicher resident machen, inklusive absolute Positionierung.
@fetch positionieren: curpos merken und optimiert (kürzester Weg) von curpos, first, last positionieren.
@Subfilegröße:
ich wage es zu bezweifeln, dass ein Benutzer wirklich 9999 Sätze blättern will, maximale Größe festlegen, count(*) vorweg und ggf Fehlermeldung und flexible Auswahl anbieten.
@ Programm merken: dto. plus mit zwei Arrays arbeiten, eins für die Position, eins für aufsetzen - Hauptspeicher schlägt Datenbank
@aufsetzen: mit zwei Cursorn arbeiten, einer ab Position vorwärts, der andere ab Position rückwärts. Cursor erst öffnen, wenn überhaupt benötigt!
@sauber: sauber ist da im engeren Sinne nix, da die Daten sich während der Anzeige ändern können, ansonsten ist der Sauberkeitsgrad bei allen Varianten gleich, wenn man das fehlerfrei programmiert.
D*B
andreaspr@aon.at
25-08-11, 11:54
Was spricht dagegen den Cursor offen zu lassen und beim Blättern normal weiter zu lesen.
Wird zurück geblättert, dann den offenen Cursor einfach um n*-Zeilen zurück positionieren und wieder weiter lesen.
Wenn du immer die aktuellen Sätze angezeigt bekommen willst, kannst du das auch mit dem Schlüsselwort SENSITIVE.
Performant ist es auch in Blöcke zu lesen. Dabei reicht es wenn n* Zeilen in ein Array gespeichert werden.
*n steht für die Anzahl an Zeilen im Subfile
Bitte nicht erschlagen!
Als Dinosaurier würde ich das mal (ganz ohne SQL) mit einer Addrout Datei versuchen. "Sort A" da habe ich dann die Satznummern nach meinem Sortierbegriff. Zugriff auf die Addroute nach Satznummer. Dann genügt ein einfaches Feld zum merken des ersten/letzten angezeigten Satzes
Nicht die neueste Methode aber führt bestimmt auch zum Ziel.
Das Problem der Aktualität ist natürlcih auch gegeben es gilt der Zeitpunkt des Sort.
Klaus
ein Sort über ein paar Millionen Sätze macht das auch nicht schneller und bezüglich der Positionierung änbdert sich da auch wenig, falls beim SQL ResultSet hinbekommt, dass von Position 220 bis 210 um 10 rückwärts positioniert werden muss.
D*B
Klabautermann
25-08-11, 12:32
Hallo,
Ich werde die Varaiante mit dem Blockfetch ausprobieren. Ich gebe bescheid, welche lösung am Performantesten ist.
@andreaspr@aon.at: Der Cursor bleibt offen. Das Problem ist, dass der "Fetch relative 3451244" zu viel performance frisst.
@K_Tippi: Auf Klassischem wege wäre das kein Problem. Dann könnte ich mir eine logische erstelle und mit SetLl/ReadE arbeiten. Leider ist das keine Option :(
Viele Grüße