2008-09-09 19 views
0

Ich versuche, die Ergebnisse einer SQL-Abfrage für die Verwendung auf einer Webseite paginieren. Die Sprache und das Datenbank-Backend sind PHP und SQLite.SQL Paginierung

Der Code Ich verwende funktioniert so etwas wie diese (Seitennummerierung beginnt bei 0)

http://example.com/table?page=0

page = request(page) 
per = 10 // results per page 
offset = page * per 

// take one extra record so we know if a next link is needed 
resultset = query(select columns from table where conditions limit offset, per + 1) 

if(page > 0) show a previous link 
if(count(resultset) > per) show a next link 

unset(resultset[per]) 

display results 

Gibt es effizientere Wege Paginierung als dies zu tun?

Ein Problem, das ich mit meiner aktuellen Methode sehen kann, ist, dass ich alle 10 (oder wie viele) Ergebnisse im Speicher speichern muss, bevor ich anfange, sie anzuzeigen. Ich tue dies, weil PDO nicht garantiert, dass der rowcount verfügbar sein wird.

Ist es effizienter, eine COUNT (*) Abfrage zu erstellen, um zu erfahren, wie viele Zeilen vorhanden sind, und die Ergebnisse dann an den Browser zu senden?

Ist dies einer dieser "es hängt von der Größe Ihrer Tabelle ab, und ob die Abfrage count (*) einen vollständigen Tabellenscan im Datenbank-Backend erfordert", "einige Profiling yourself" Art von Fragen?

Antwort

1

ich würde vorschlagen, nur die Zählung zuerst. Eine Zählung (Primärschlüssel) ist eine sehr effiziente Abfrage.

+4

... solange Sie nicht (WHERE) auf eine Spalte ohne Index filtern und keine Joins verwenden :) – BlaM

1

Ich bezweifle, dass es ein Problem für Ihre Benutzer sein wird, zu warten, bis das Backend zehn Zeilen zurückgibt. (Sie können es schaffen, indem Sie die Bilddimensionen gut angeben, den Webserver veranlassen, komprimierte Datenübertragungen auszuhandeln, wenn möglich, usw.)

Ich denke nicht, dass es sehr nützlich für Sie sein wird, zu zählen (*) anfänglich.

Wenn Sie eine komplizierte Codierung haben: Wenn der Benutzer Seite x betrachtet, verwenden Sie ajaxähnliche Magie, um Seite x + 1 für eine verbesserte Benutzererfahrung vorzuladen.

Eine allgemeine Notiz Paginierung: Wenn sich die Daten ändern, während der Benutzer durch Ihre Seiten blättert, es kann ein Problem sein, wenn Ihre Lösung ein sehr hohes Maß an Konsistenz verlangt. Ich habe eine Notiz darüber geschrieben .

2

Ich habe mich entschieden, mit der COUNT (*) zwei Abfrage-Methode zu gehen, weil es mir erlaubt, einen Link direkt auf die letzte Seite zu erstellen, was die andere Methode nicht erlaubt. Wenn ich zuerst die Zählung durchführe, kann ich auch die Ergebnisse streamen und sollte daher mit einer höheren Anzahl von Datensätzen mit weniger Speicher gut funktionieren.

Konsistenz zwischen den Seiten ist kein Problem für mich. Danke für Ihre Hilfe.

2

Es gibt mehrere Fälle, in denen ich eine ziemlich komplexe (9-12 Tabellen Join) Abfrage habe, die viele tausend Zeilen zurückgibt, die ich paginieren muss. Um schön zu paginieren, müssen Sie die Gesamtgröße des Ergebnisses kennen. Bei MySQL-Datenbanken kann die Verwendung der Anweisung SQL_CALC_FOUND_ROWS in SELECT Ihnen dabei helfen, dies zu erreichen, obwohl die Jury sich darüber im Klaren ist, ob dies für Sie effizienter ist.

Da Sie jedoch SQLite verwenden, empfehle ich, mit dem 2-Abfrage-Ansatz zu bleiben. Here ist ein sehr prägnanter Thread zu diesem Thema.