是否可以缓存分页查询的计数结果?
select count(*) as aggregate from table_name
我的桌子有2 000 000+,每次计算此计数大约需要300毫秒。将结果缓存1小时将是足够的解决方案,谢谢!
答案 0 :(得分:0)
我需要扩展Illuminate\Database\Eloquent\Model
和Illuminate\Database\Eloquent\Builder
。
我的扩展Builder类
<?php
namespace App\Laravel\Database\Eloquent;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Cache;
/**
* @mixin \Illuminate\Database\Query\Builder
*/
class CachedBuilder extends Builder
{
const CACHE_THRESHOLD = 10000;
const CACHE_DURATION = 60;
const CACHE_KEY_PREFIX = 'pagination_';
/**
* 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();
$key = self::CACHE_KEY_PREFIX . '_' . $this->getModel()->getTable();
$total = Cache::get($key);
if(!$total) {
$total = $this->toBase()->getCountForPagination();
if($total > self::CACHE_THRESHOLD) {
Cache::put($key, $total, self::CACHE_DURATION);
}
}
$results = $total ? $this->forPage($page, $perPage)->get($columns)
: $this->model->newCollection();
return $this->paginator($results, $total, $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]);
}
}
我的扩展模型课程
<?php
namespace App\Laravel\Database\Eloquent;
use Illuminate\Database\Eloquent\Model;
abstract class CachedModel extends Model
{
/**
* @param \Illuminate\Database\Query\Builder $query
* @return CachedBuilder|\Illuminate\Database\Eloquent\Builder|static
*/
public function newEloquentBuilder($query)
{
return new CachedBuilder($query);
}
}
现在我只需要使用这个新的CachedModel类扩展我的任何模型,即可应用总计数结果的缓存。