webadmin 分页查询优化

Achun

关于后台查询,自动分页的简单优化

可以看到我这里后台的数据已经达到了1亿,使用后台自动分页已经非常的慢(一点也不夸张的说)

截图


截图


找到后台控制器的继承类 Crud
截图


看了下代码不出意外就是这个查询每次都统计总数造成的

有没有什么办法能缓存每次的统计总数呢?

很简单,那就使用tosql()来判断,根据查询条件来缓存匹配当前总条数

查了一下文档,因为使用的是laravel的paginator,那就意味着可以用simplePaginate

如果使用simplePaginate, 不会计算总行数,查询会比paginate快很多。不过你也因此不能知道总页数,没办法跳到任意页。

$paginator->total() 获取结果集中的数据总数(在 simplePaginate 中不可用)
这个可以每次统计后保存下来

那么避免污染其他模型,直接在当前控制器重写

protected function doFormat($query, $format, $limit): Response
    {
        $methods = [
            'select' => 'formatSelect',
            'tree' => 'formatTree',
            'table_tree' => 'formatTableTree',
            'normal' => 'formatNormal',
        ];
        $key = $query->toSql();
        // 先记录sql条件作为键值
        if(Redis::get($key)){
            $total = Redis::get($query->toSql());
        }else{
            $total = $query->count('*');
            Redis::set($key,$total,'EX',3600); //缓存时间根据业务调整
        }
        $paginator = $query->simplePaginate($limit);

//        $paginator = $query->paginate($limit);
//        $total = $paginator->total();
        $items = $paginator->items();
        if (method_exists($this, "afterQuery")) {
            $items = call_user_func([$this, "afterQuery"], $items);
        }
        $format_function = $methods[$format] ?? 'formatNormal';
        return call_user_func([$this, $format_function], $items, $total);
    }

因为涉及到数据新增的情况,需要在当前表新增数据的时候
清空所有select能模糊匹配的key(+1只适合一些情况)
截图

直接看查询结果,起飞~

截图

目前手动添加查询条件(一些复杂查询),redis key 匹配会有问题,自行打印排除解决
截图
可以看到这里语句打印出来是预编译,为防止key匹配失败--需要将查询的值拼接在key上.

最后还要提一句,如果涉及到offset值过大一样会变慢,这种时候就要考虑使用子查询索引优化

278 4 3
4个评论

efnic

感谢分享。

  • 暂无评论
ersic

很有用的分享

  • 暂无评论
德玛西亚

感谢分享。

  • 暂无评论
dj880

感谢分享~

  • 暂无评论

Achun

420
积分
0
获赞数
0
粉丝数
2023-12-04 加入
×
🔝