是否有可能缓存分页查询的计数结果?
select count(*) as aggregate from table_name
我有 2 000 000+ 的表,每次计算这个计数需要大约 300 毫秒。将此结果缓存 1 小时就足够了,谢谢!
是否有可能缓存分页查询的计数结果?
select count(*) as aggregate from table_name
我有 2 000 000+ 的表,每次计算这个计数需要大约 300 毫秒。将此结果缓存 1 小时就足够了,谢谢!
我需要扩展Illuminate\Database\Eloquent\Model
和 Illuminate\Database\Eloquent\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 类扩展我的任何模型,以应用总计数结果的缓存。