Welcome Guest, Not a member yet? Register   Sign In
Pagination Inefficiency 4.0.4
#1

(This post was last modified: 09-01-2020, 03:10 AM by Gary.)

I stand under possible correction (it may well be that I’m just using CI’s pagination functionality in an obtuse and unintended manner), but there appears to be a notable inefficiency in the pagination as it currently stands.

Typically one would use it as such (in the manual mode, though I suspect it may also affect the other ways pagination is used too):

Code:
$query_page_array = $model->where('id', $ id)->whereIn('condition’, CONDITION_ARRAY)->whereIn(other conditions)…(…)->paginate($perPage, 'page-group', $pageCurrent, $urlSegment);

$pager_links = $pager->makeLinks($pageCurrent, $perPage, $totalNumberItems, 'template', $urlSegment, 'page-group');

The inefficiency appears to be in having to manually calculate $totalNumberItems before generating $pager_links… which requires a (possibly time-consuming) query almost identical to the one just used to generate the ->paginate() results for $query_page_array.

Inside the system Model.php’s paginate() function, it appears that there is already a $totalNumberItems (called $total) of all the results that is calculated, and stored into an instance of Pager: 
Code:
$total = $this->countAllResults(false);
// Store it in the Pager library so it can be
// paginated in the views.
$this->pager = $pager->store($group, $page, $perPage, $total, $segment);

One may also notice that many of the same variables are stored to the instance of Pager again in the system Pager.php’s makeLinks() function:
Code:
$this->store($group, $page, $perPage ?? $this->config->perPage, $total, $segment);

Some of these repeated arguments to makeLinks(), I suspect, could probably also be removed (?)… though, they aren’t as significant because they don’t force a redundant database query to calculate $totalNumberItems (the $total variable).

One minor issue in reusing $total that will prevent it from working straight-off is that, for some (possibly good?) reason, the Model’s paginate function invokes an instance of the Pager service in a NON-SHARED mode (which seems to be a mistaken choice (?), though I am a complete novice programmer and am taking a stab in the dark on this Wink ):
Code:
public function paginate(int $perPage = null, string $group = 'default', int $page = null, int $segment = 0)
{
  $pager = \Config\Services::pager(null, null, FALSE); // FALSE = non-shared.  This needs to be changed to TRUE to make this version of the Pager service accessible to the rest of the application

Looking at the Model’s paginate() function as I write this, I see that it does also appear to try to recover existing settings further down in the function… using getCurrentPage($group)… which (if it’s an unshared instance) I’m not sure would get anything besides its own instance of the configuration (which I’m guessing would always be empty at this point in the code’s execution).

Would it make sense to make the $totalNumberItems argument as optional in the places it is used (with a default of NULL), and then in the system Pager.php store() function, simply put in a fetch from the existing configuration if it has been called using a NULL:
Code:
public function store(string $group, int $page, int $perPage = null, int $total = NULL, int $segment = 0)
{
  $total = $total ?? $this->groups[$group]['total']; // new line inserted to fetch the existing value if one is not passed in on the call
Reply




Theme © iAndrew 2016 - Forum software by © MyBB