Pagination (Seitenausgabe) ermöglicht die Verarbeitung großer SELECT-Ergebnisse ohne übermäßige Belastung des Servers und der Anwendung. Die Hauptansätze:
Beispiel (LIMIT/OFFSET)
SELECT * FROM Orders ORDER BY OrderID LIMIT 100 OFFSET 1000;
Dieser Abfrage gibt die 1011–1110. Einträge zurück. Aber OFFSET zwingt den Server, trotzdem die ersten 1000 Zeilen zu sortieren und zu überspringen — weshalb es bei tiefer Pagination langsam wird.
Beispiel (Keyset/Seek-Methode)
SELECT * FROM Orders WHERE OrderID > 1110 ORDER BY OrderID LIMIT 100;
Eine solche Abfrage findet schnell die nächste Seite, ohne Ressourcen für die Berechnung des OFFSET zu verschwenden, besonders effektiv bei vorhandenem Index auf OrderID.
Haken: "Warum kann Pagination über LIMIT/OFFSET bei großen Datenmengen schlecht funktionieren und wie kann man das verbessern?"
Antwort: Die Schwierigkeit liegt darin, dass OFFSET den Server zwingt, alle vorherigen Zeilen zu scannen und zu sortieren — je tiefer man in den Seiten geht, desto langsamer wird es. Die Optimierung besteht darin, auf Keyset/Seek-Paging umzusteigen: nicht nach Versatz zu wählen, sondern nach dem Schlüssel des letzten Eintrags der vorherigen Seite.
-- Nächste Seite nach Schlüssel erhalten SELECT * FROM Orders WHERE OrderID > @LastOrderID ORDER BY OrderID LIMIT 100;
Geschichte
Projekt: Marktplatz, Bestelldaten über 5 Jahre (50 Millionen Zeilen)
Fehler: OFFSET zur Pagination von Bestellungen alter Benutzer verwendet. Abfragen mit OFFSET > 1 Million begannen, 30–60 Sekunden zu dauern. Dies beeinträchtigte Berichte und API-Schnittstellen — dadurch wurden CPU-Server belastet und die Wartezeit in der Warteschlange stieg an.
Geschichte
Projekt: Unternehmens-CRM, Berichte über Kunden.
Fehler: Bei der Pagination wurde die Sortierreihenfolge nicht berücksichtigt und keine Indizes verwendet. Dies senkte die Leistung und die Integrität der Abfragen — Benutzer erhielten dieselben Zeilen auf verschiedenen Seiten bei Änderungen in der Tabelle.
Geschichte
Projekt: Finanzplattform, Dashboards.
Fehler: Komplexe Paginationen wurden über generierten dynamischen SQL ohne Bind-Variablen erstellt, was zu SQL-Injektionen und Problemen mit der Unterstützung der Transaktionsfähigkeit zwischen den Datenseiten führte.