Christian Kruse: dynamische Paginierung - gegen "leere" Seiten

Beitrag lesen

Hallo Felix,

Mir ist aufgefallen, dass ich nach dem Verbergen von Threads plötzlich weniger Threads auf meiner Forenseite angezeigt bekomme. Grundsätzlich ist das nicht verkehrt, aber da die Nummerierung der Paginierung bis über 4000 geht (dem Archiv sei Dank), entsteht so manche leere Seite, da sie nur ausgeblendete Threads enthält.

Naja, das Problem ist komplexer (und interessanter): in einem MVCC-DBMS muss eine Datenbank für ein count(*) alle in Frage kommenden rows durchgehen und prüfen, ob die Reihe für die aktuelle Transaktion sichtbar ist oder nicht. Deshalb dauert ein count(*) halt wirklich lange, es müssen knapp 250k Zeilen geprüft werden. Das wird zwar durch die ausgeblendeten Threads (die übrigens nie so gedacht waren wie du sie verwendet hast ;) etwas weniger, aber das macht den Kohl nicht fett.

Edit: Das braucht mehr Erklärung. Um das Problem zu umgehen arbeite ich mit einer Counter-Table. Jedesmal, wenn ein Thread oder eine Nachricht erstellt oder gelöscht wird, wird über einen Trigger ein Eintrag in dieser Form gemacht:

threads  | meta | +1
threads  | self | +1
messages | meta | +1
threads  | self | -1

Das hat zwei Vorteile: einerseits brauche ich das teure count(*) und zweitens, im Gegensatz zu z.B. einem Attribut messages an der Forums-Row, ist das völlig lockfrei und damit unproblematisch für Concurrency. Die Anzahl für ein Forum gibt mir eine Pl/pgSQL-Funktion zurück, die auch bei mehr als 100 Datensätzen für eine Gruppierung mir die Datensätze zusammenfasst. Auf das Beispiel oben angewandt:

threads | self | 0

Das hat aber den Nachteil, dass man beim Zählen dann deutlich unflexibler wird.

Meines Erachtens gibt es dafür zwei mögliche Lösungen: entweder auf genaues Paging verzichten. Dann geht aber auch dieArbeitsweise wie sie Martin z.B. praktiziert nicht mehr, er könnte ja nicht mehr auf die letzte Seite springen. Das wäre der Ansatz, wie ihn die meisten Projekte fahren, etwa Google. Die andere Lösung wäre das Archiv prinzipiell auszublenden auf der Hauptseite. Dann ist der Datenbestand halt deutlich viel kleiner und man gefahrlos ein count(*) drauf loslassen.

LG,
CK