For large offsets, MySQL needs to look at more records.
Even if filesort used in the plan (this means that all records must be viewed), MySQL optimizes it to sort only the top records $offset + $limit , which makes it much more efficient for lower $offset values.
A typical solution is to index the columns that you order, write the last column value and reuse it in subsequent queries, for example:
SELECT * FROM mytable ORDER BY value, id LIMIT 0, 10
which outputs:
value id 1 234 3 57 4 186 5 457 6 367 8 681 10 366 13 26 15 765 17 345 -- this is the last one
To go to the next page, you should use:
SELECT * FROM mytable WHERE (value, id) > (17, 345) ORDER BY value, id LIMIT 0, 10
which uses an index on (value, id) .
Of course, this does not help with arbitrary access pages, but it helps with sequential viewing.
In addition, MySQL has certain problems finding on the last line. If the columns are indexed, it might be worth trying to rewrite your query as follows:
SELECT * FROM ( SELECT id FROM mytable ORDER BY value, id LIMIT $offset, $limit ) q JOIN mytable m ON m.id = q.id
See this article for more explanation:
Quassnoi
source share