This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information

Pagination

Allgemeine Fragen zur Entwicklung von und mit JVx.

Pagination

Postby Jan » Thu Apr 28, 2011 2:01 pm

Hallo,

ich möchte gerne große Datenbestände aus einer Datenbank darstellen und laufe damit in Speicherprobleme. Was sollte ich ideallerweise wie in MemDataBook und MemDataPage anstellen, um ein speicherschonendes Paging hinzubekommen?

VG Jan
Jan
 
Posts: 3
Joined: Thu Apr 28, 2011 1:43 pm

Re: Pagination

Postby Support@SIB » Thu Apr 28, 2011 2:39 pm

Hast du ein Problem mit großen Datenbeständen und JVx bzw. möchtest du den Load-on-demand Mechanismus von JVx selbst entwickeln? Oder verwendest du ein MemDataBook anstatt eines RemoteDataBooks?

Bitte gib uns ein paar Details damit wir über das gleiche Thema sprechen können.
User avatar
Support@SIB
 
Posts: 349
Joined: Mon Sep 28, 2009 1:56 pm

Re: Pagination

Postby Jan » Thu Apr 28, 2011 4:31 pm

Danke für die schnelle Reaktion. Ich habe die Showcase-Applikation als Grundlage genommen und StoragesFrame so abgewandelt, dass im Grid die Werte aus einer Datenbanktabelle dargestellt werden, die einige Millionen Einträge enthält. Diese Anzahl von Einträgen halte ich bei Geschäftsanwendungen für nicht ungewöhnlich.

RemoteDataBook ist von MemDataBook und RemoteDataPage von MemDataPage abgeleitet. Über fetchToRow() in RemoteDataPage werden die Zeilen der Datenbank in der Membervariable alStorage in MemDataPage im Bedarfsfall (beim Runterscrollen oder bei Auswahl der Sortierung sofort alle Daten(fetchAll() bei bMemSort = true) nacheinander gespeichert.

Nun treten zwei unschöne Effekte auf:

1. Der Speicher läuft zu.
2. Selbst bei einer DirectServerConnection und der Datenbank auf demselben Rechner benötigt ein fetchAll() eine gewisse Zeit. Bei einer HttpSession würde zudem damit das Netz erheblich belastet.

Schön wäre, wenn neben der bestehenden Implementierung eine Möglichkeit eröffnet würde, die Daten aus der Datenbank mittels Paging netzwerkschonend zum Client zu übertragen und speicherschonend im Client vorzuhalten.

Nun stellt sich die Frage, wie sich so etwas möglichst einfach realisieren lässt.

VG Jan
Jan
 
Posts: 3
Joined: Thu Apr 28, 2011 1:43 pm

Re: Pagination

Postby mhandsteiner » Thu Apr 28, 2011 7:01 pm

Vielen Dank für die genaue Darstellung des Problems.

1) fetchAll bei großen Datenmengen

Bei großen Datenmengen sollte auf keinen Fall die MemSort oder MemFilter Option eingeschalten werden.
So ist gewährleistet, dass die Sortierung und das Filtern an die Datenbank delegiert wird, und am Client kaum Speicher und Rechenleistung verbraucht wird.

Somit kann man nur mit "nach unten scrollen" die Datenzeilen erreichen.

Dabei entsteht Performancetechnisch kein Vor- oder Nachteil gegenüber einem Paging, da immer nur die fehlenden Zeilen gefetcht werden.

Selbst wenn man bei einem Paging direkt auf die letzte Page springen würde, muss der JDBC Driver die Zeilen davor lesen, was gleich lange dauert.

Das Übertragen zum Client erfolgt höchst optimiert, geblockt und gezipped, was dazu führt, dass in der Praxis nur die Dauer des JDBC-Drivers ausschlaggebend ist,
also kaum ein Unterschied zwischen DirectServerConnection und HttpConnection festzustellen ist.

Beim zurück scrollen müssten bei einer Paging Variante die Daten erneut gefetcht werden, was durch das Merken der bis dahin gefetchten Zeilen entfällt.

Um den Speicherverbrauch am Client möglichst gering zu halten, werden die Objekte (BigDecimal, String, Timestamp, ...) "internalized", also singleton gespeichert.

Nichts desto Trotz, ist die Aussage völlig richtig, dass, wenn ein Benutzer geduldig nach unten scrollt, früher oder später alle Datenzeilen am Client landen.

Dazu gibt es zu Zeit 2 Vorgehensweisen:

a) Man stellt eine Filtermöglichkeit zur Verfügung.
Der Benutzer wird, bevor er Minuten lang scrollt eher eine Filterbedingung eingeben, oder die
Datenzeilen so sortieren, dass seine gewünschten Datenzeilen oben landen.
So erhält er schnell die gewünschten Zeilen, kann aber trotzdem nach unten scrollen, bis Ihn die
Geduld verläßt (oder ein Out of Memory passiert...)
b) Man gruppiert die Daten in einer Master Detail Beziehung in der Art, dass der Benutzer auch schnell
und übersichtlich seine Daten findet
Bsp: Mails von diesem Monat, letztem Monat, vorletztem Monat, ...
Bei so vielen Datensätzen hat man fast immer eine fachliche Strukturierung.
Ich hatte mal ein Projekt, mit mehr als 3 Milliarden Messdaten, wo der Benutzer mit ein paar Clicks
(Gebiete Hierachisch Bsp. Österreich, Wien, 18.Bezirk, und Zeit Bsp letzte Woche) in
Sekundenschnelle die richtigen Daten zu Gesicht bekommt.

Generell kann man sich noch absichern, und:
a) Speicherverbrauch des Clients testen, und genügend Heap zur Verfügung stellen.
b) Maximale Anzahl der Zeilen, die zum Client geschickt werden, begrenzen.

2) Paging

Paging hätte von vorn herein keine Möglichkeit, am Client zu sortieren, und oder zu filtern, (nur innerhalb der Page, was nichts bringt).

Wenn der Benutzer die richtige Page finden will, muss er auch Seite für Seite weiterclicken, was wie gesagt Performance technisch keinen Vorteil bringt.

Einfache Umsetzung wäre trotzdem möglich, mit 2 RemoteDataBooks:
1. Paging Book, liefert z.B. Page 1, Page 2, Page 3, ... Page (rowCount + 1) / pagesize - 1
2. Data Book, mit geänderter DBStorage, die ein Limit mit [(page# - 1) * pagesize + 1, page# * pagesize - 1] absetzt
3. AfterRowSelected Listener am Paging Book, in dem man das Data Book reloaded, um alle alten Pages zu verwerfen.
(Könnte man eventuell so gestalten, dass man n pages cached, um die Netzwerklast zu reduzieren)

Technisches Problem generell ist bei solchen Methoden, dass man in einer Multi User Umgebung nie wissen kann, ob nicht anderere Benutzer
inzwischen auf irgendeiner Page Zeilen eingefügt, oder gelöscht haben.
Es könnte sein, dass man eine Seite zurück geht, und die selben Zeilen wieder sieht, weil andere Benutzer davor Zeilen gelöscht haben.

3) Gute Idee, mögliche Alternative

An und für sich halte ich die Idee für sehr gut, in einer RemoteDataPage die Möglichkeit vorzusehen, eine "Maximal Anzahl von Datenzeilen Cache" zu unterstützen.
Also, wenn man in einer Tabell nach unten scrollt, und bei Zeile 11000 (bei zB MaxCacheSize = 10000) angelangt ist, das man beginnt, die Zeilen von 1 - 1000 verwirft,
und sich einen firstRow Index 1000 merkt.
Scrollt man wieder nach oben und kommt in den Bereich von < 1000, fetcht man wieder die Zeilen 1 - 1000, und verwirft die Zeilen > 10000.

Dies wäre einfach umzusetzen, hat aber die selben technische Nachteile wie das Paging, in einer Multiuser Umgebung, bzw bei komplizierten Views.

Vorteile:
- einfache Implemetierung
- einfache Konfiguration für einen Entwickler, keine sonstige Logik Änderung notwendig.
- Extrem Speichersparsam

Nachteile:
- Eindeutigkeit der Datenzeilen nicht gewährleistet, da mehrere Selects pro RemoteDataPage abgesetzt werden
- Mehr Netzwerk Traffic, da Daten, die bereits im Speicher waren immer wieder gefetcht werden
- Langsamer, da das Absetzen von unabhägigen limit selects länger dauert, wie ein select mit offen
gehaltenem cursor gerade bei komplexeren Selects kann dies ein Knock out sein.

Da ich die Idee für sehr Gut halte, werde ich einen Feature Request erfassen.
mhandsteiner
 
Posts: 15
Joined: Mon Sep 28, 2009 2:17 pm

Re: Pagination

Postby Jan » Thu Apr 28, 2011 8:22 pm

Vielen Dank!

VG Jan
Jan
 
Posts: 3
Joined: Thu Apr 28, 2011 1:43 pm


Return to Development (DE)