I wonder how can I get the "total_items", when the query ($get) has not run yet... This means I'd have to double my query adding the `COUNT(*)` function and removing the limits on it... this seems pointless, really. My query is quite large and I'm caching it in order to save the execution time.
There should be some possibilities to set the total_items AFTER the pagination forge and then it should rebuild the pagination results.
// set pagination information \Pagination::instance()->uri_segment = 4; \Pagination::instance()->per_page = \Config::get('application.pagination', 20); \Pagination::instance()->total_items = $query->count(); \Pagination::instance()->pagination_url = \Uri::create('finance/invoices/search');
// content for this action \Theme::instance()->set_partial('content', 'invoices/index') ->set('invoices', $query->order_by('name', 'ASC') ->rows_offset(\Pagination::instance()->offset) ->rows_limit(\Pagination::instance()->per_page) ->get());
If you cache the results, you should also cache the totals, otherwise your data is inconsistent. There is no way to calculate totals from a cached subset of data.
Doesn't matter, you still need to run it once without the LIMIT and OFFSET to get the total number of rows in the result, which is required to calculate the number of pages.
With 500K rows, how pointless is this in a paging context? How many pages does that produce? And which user is going to page through them all?
To work around that, you would need something like open-ended pagination, where there is no "last page" defined, but you check, when you request the next page, if you have any results and if not, display a message that you are on the last page. Problem is when you only have 10 pages, and a user requests page 100. It's a bit resource heavy to start requesting pages from 99 down until you get a hit...
Indeed I wont paginate the whole 500K rows because that would be really pointless, the table itself contains 500K rows, but there are some conditions in the query so the final output would be smaller, plus I'm making an overall limit.
Just curious, what is the Model\Invoice::query() function?
To avoid the double query, I would probably do: - set the total pages hard coded to something very high - configure pagination to NOT show a 'last page' marker - cache the page results - run only the limit/offset query if no cache for that page is present, and cache the result - display an error message and go back to the previous page if the page has no results
This should give you the least amount of queries which still keep it usable for your users.