読者です 読者をやめる 読者になる 読者になる

QueryBuilder::paginate() と Eloquent::paginate() の挙動の違いがあった

 

Laravel ver: 5.3.26

 

SQL的にcount() で取得するときには、主にそのテーブルの主キーをあてるほうがより速く実行することが出来ます。

 

今回、QueryBuilder::paginate() と Eloquent::paginate() の挙動の違いがあったためメモします。

データを取得するとき、第二引数に$column (default =['*']) を指定することが出来ます。

 

今回、DBオブジェクトが持ってるQueryBuilder::paginate()の場合だと、

/**
* Paginate the given query into a simple paginator.
*
* @param int $perPage
* @param array $columns
* @param string $pageName
* @param int|null $page
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null)
{
$page = $page ?: Paginator::resolveCurrentPage($pageName);

$total = $this->getCountForPagination($columns);

$results = $total ? $this->forPage($page, $perPage)->get($columns) : collect();

return new LengthAwarePaginator($results, $total, $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]);
}

 

 

    $total = $this->getCountForPagination($columns);
}

 

で、countを取得しています。

 

一方、Modelオブジェクトが持っているEloquent::paginate()だと、

 

/**
* Paginate the given query.
*
* @param int $perPage
* @param array $columns
* @param string $pageName
* @param int|null $page
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*
* @throws \InvalidArgumentException
*/
public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
{
$page = $page ?: Paginator::resolveCurrentPage($pageName);

$perPage = $perPage ?: $this->model->getPerPage();

$query = $this->toBase();

$total = $query->getCountForPagination();

$results = $total
? $this->forPage($page, $perPage)->get($columns)
: $this->model->newCollection();

return new LengthAwarePaginator($results, $total, $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]);
}

 

    $total = $query->getCountForPagination();

 

と、$column名が引数に渡ってないため、呼ぶ側が明示してもcount(*) と実行されるみたいです。

 

以上、使ってみて気づいたことでした。

 

本体に報告してみたいのですがやり方はまた調べて、fixしてもらえるようにしたいと思います。