Es geht nur um Caching.
Einfach gesagt, OFFSET
saugt. Es muss alle "Offset" -Reihen lesen und ignorieren und dann "Limit" -Reihen liefern.
Wenn die Zeilen übersprungen werden, müssen sie die Zeilen holen - wenn sie auf der Festplatte sind, braucht es Zeit; Wenn sie im RAM zwischengespeichert werden, ist es viel schneller. (Oft 10-mal so schnell.)
Was wahrscheinlich passiert in Ihrem Fall: Die erste Abfrage gefunden wenige, wenn überhaupt, der Zeilen im RAM, so dass es die meisten oder alle 1999950 Zeilen hatte.
Dann hat Ihre zweite Abfrage die 1999950 Zeilen schnell gescannt und dann die letzten 50 von der Festplatte abgerufen. (. Oder vielleicht die letzten 50 bereits hereinkam, da die Einheit von I/O ist ein „Block“ von Datensatz)
Mit LIMIT
und/oder OFFSET
, gibt EXPLAIN
selten irgendwelche Hinweise - es gibt in der Regel eine Schätzung der Gesamtzahl der Zeilen in der Tabelle.
Es gibt noch ein anderes Problem mit Ihren Beispielen ... Sie haben keine ORDER BY
. So kann der Motor beliebige Reihen liefern. Normalerweise ist es vorhersehbar, aber manchmal kann es Überraschungen geben.
Aber, sobald Sie ein ORDER BY
hinzufügen, es kann Bedarf eine temporäre Tabelle und sortieren noch bevor immer den ersten Datensatz zu sein! Das heißt, SELECT ... ORDER BY .. LIMIT 50
kann so langsam sein wie alle anderen - wenn Sie etwas Unangenehmes für die Indizes usw. bestellen, die beteiligt sind.
Siehe how OFFSET sucks when paginating web pages. Das beinhaltet eine Problemumgehung durch "Erinnern, wo Sie aufgehört haben". Und this zeigt, wie man die nächsten 1000 Zeilen effizient erhält, sogar mit Lücken in IDs.
Höher der Offset langsamer die Abfrage. Related [** post **] (http://stackoverflow.com/questions/4481388/why-does-mysql-higher-limit-offset-slow-the-query-down) – 1000111
Versuchen Sie, die Verwendung von Offset – Mike
zu vermeiden Ist dieser Bug oder diese Einschränkung, benutze ich ihn um die Paginierung der Seite aufzulisten. :(jede andere Lösung? – user3151197