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してもらえるようにしたいと思います。