LIMIT & Gesamtzahl der Datensätze
Rouven
- datenbank
0 Tom2
Hallo zusammen,
folgendes Problem/folgende Frage:
Ich möchte in mein PHP-Skript eine Art Blättern-Funktion analog zu Suchmaschinen etc. einbauen.
Dazu möchte ich unter MySQL die LIMIT x,y-Funktionalität benutzen.
Nun brauche ich aber z.B. für eine Schaltfläche "Zur letzten Seite springen" die Gesamtzahl der Ergebnisse der Abfrage.
Gibt es eine Möglichkeit diese zu erfahren ohne eine COUNT(*)-Abfrage auf den selben Daten ohne LIMIT zu machen?
Ich weiß von IBM, dass dort die Datenbank eine Variable TOTAL-ROWS hält die unabhängig von irgend einem Limit die Gesamtzahl der Datensätze ermitteln kann, bzw. die Datenbank eine SIZE der Abfrage zurückgibt.
Thanx!
Rouven
Hi Rouven
Gibt es eine Möglichkeit diese zu erfahren ohne eine COUNT(*)-Abfrage auf den selben Daten ohne LIMIT zu machen?
AFAIK gibt es keine andere Möglichkeit, aber wenn du COUNT() auf nur eine Spalte legst, die wenn möglich sogar noch indexiert ist, dann sollte das einigermassen performant laufen. Ich kann dir das zwar nicht garantieren, aber für mich scheint dies logisch. Korrigiert mich, wenn ich falsch liege.
MfG
Tom2
Hi Tom2,
Gibt es eine Möglichkeit diese zu erfahren ohne eine COUNT(*)-Abfrage auf den selben Daten ohne LIMIT zu machen?
AFAIK gibt es keine andere Möglichkeit, aber wenn du COUNT() auf nur eine Spalte legst, die wenn möglich sogar noch indexiert ist, dann sollte das einigermassen performant laufen. Ich kann dir das zwar nicht garantieren, aber für mich scheint dies logisch. Korrigiert mich, wenn ich falsch liege.
ich kann auch nur eine Theorie dazu äußern. Diese lautet jedoch: "Das kommt darauf an".
Gerade _wenn_ über der Spalte ein Index liegt, dann würde mich wundern, wenn man zusätzlich zu den nach dieser Spalte sortierten und danach limitierten Treffern auch noch die Gesamtzahl der Ergebnisse erfahren würde.
Denn der Trick dabei ist doch gerade, daß die Treffer in diesem Falle bereits in der sortierten Reihenfolge vorliegen. Was tut das RDBMS also? Es traversiert den Index-Teilbaum der erwünschten Treffer und bricht ab, sobald es das LIMIT erreicht hat.
Danach noch die Gesamtzahl aller möglichen Treffer zu berechnen kann irre teuer werden (schlimmer als ein full table scan!) und den Nutzeffekt des Index mehr als zunichte machen.
Die Rettung wäre es, wenn das RDBMS innerhalb _jedes_ einzelnen Knotens innerhalb des Indexbaums (!) zusätzlich die Information ablegen würde, wie viele Knoten innerhalb des darunter liegenden vollständigen Teilbaums enthalten sind. In diesem Falle könnte der Index-Traversierer die Gesamtzahl der Treffer sehr schnell durch Addition der Werte aller relevanten Wurzelknoten bestimmen (das kann mehr als einer sein, je nach "Gestalt" des Baums). Dies funktioniert jedoch nur, wenn der zum Sortieren verwendete Index auch allein (!) für die Befriedigung der WHERE-Klausel zuständig ist ... sobald dort noch zusätzliche Bedingungen auftreten, sind die Knotenzahlen innerhalb des Baums nutzlos.
Und bedenke dabei, daß diese Knotenzahlen extrem aufwändig zu pflegen wären: Jeder INSERT und jedes DELETE bewirkt eine Änderung in _jedem_ Knoten auf dem Traversierungspfad zum betroffenen Knoten! (Bei einer Tabelle mit wenigen Schreib-, aber vielen Lesezugriffen könnte sich das dennoch lohnen.)
Hat die Datenbank jedoch _nicht_ die Möglichkeit, das (vorhandene) Sortier-Kriterium über einen Baum abzuwickeln (weil WHERE und ORDER BY nicht über einen _gemeinsamen_ Index befriedigt werden können), dann muß sie zuerst mal alle Treffer berechnen (sonst könnte sie ja die 'besten' Treffer übersehen) und mit diesen dann eine Sortierung beginnen. In diesem Fall weiß sie bestimmt die Gesamtzahl aller Treffer.
Das LIMIT schlägt dann 'nur' beim Sortieren zu, wo die 10 kleinsten Werte aus 10000 Treffern zu finden mit trivialem Bubblesort natürlich viel schneller geht, als alle 10000 Werte mit Quicksort zu sortieren und danach 9990 Treffer wegzuwerfen. Und da das Finden der Zeilen üblicherweise linearen Aufwand erfordert, das Sortieren aber n * log(n), wird das Sortieren bei großen Trefferzahlen den deutlich überwiegenden Anteil der Rechenzeit einnehmen - die LIMIT-Klausel kann also auch in diesem Falle eine erhebliche Beschleunigung bewirken.
Viele Grüße
Michael