【问题标题】:Laravel Eloquent Caching pagination aggregate count resultLaravel Eloquent Caching 分页聚合计数结果
【发布时间】:2018-12-12 23:10:45
【问题描述】:

是否有可能缓存分页查询的计数结果?

select count(*) as aggregate from table_name

我有 2 000 000+ 的表格,每次计算这个计数需要大约 300 毫秒。将此结果缓存 1 小时就足够了,谢谢!

【问题讨论】:

    标签: laravel eloquent laravel-5.6 laravel-cache


    【解决方案1】:

    我需要扩展Illuminate\Database\Eloquent\ModelIlluminate\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 类扩展我的任何模型,以应用总计数结果的缓存。

    【讨论】:

      猜你喜欢
      • 2015-07-17
      • 2013-01-30
      • 2015-06-06
      • 2017-05-01
      • 1970-01-01
      • 2015-07-22
      • 2019-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多