zoukankan      html  css  js  c++  java
  • with查询

    关联查询

     DB::enableQueryLog();
            $filter = [];
            $filter['course_id'] = $course_id;
    //        $filter['with']['user'] = [];
            CourseUser::items($filter);
            $query =DB::getQueryLog();
            return self::success($query);

    打印出的sql执行如下

     {
                "query": "select count(*) as aggregate from `wm_course_user` where (`wm_course_user`.`is_delete` = ?)",
                "bindings": [
                    0
                ],
                "time": 0.28
            },
            {
                "query": "select `wm_course_user`.`id`, `wm_course_user`.`user_id`, `wm_course_user`.`course_id`, `wm_course_user`.`created_at` from `wm_course_user` where (`wm_course_user`.`is_delete` = ?) order by `wm_course_user`.`id` desc limit 20 offset 0",
                "bindings": [
                    0
                ],
                "time": 0.28
            }

    发现我不取用关联的数据,不会执行sql查询,这就是懒加载。现在我去使用关联的数据,看下查询

    DB::enableQueryLog();
            $filter = [];
            $filter['course_id'] = $course_id;
    
    //        $filter['with']['user'] = [];
            $items = CourseUser::items($filter);
            foreach($items as $value){
                var_dump($value->user->name);
            }
            $query =DB::getQueryLog();
            return self::success($query);

    打印执行的sql如下

    {
                "query": "select count(*) as aggregate from `wm_course_user` where (`wm_course_user`.`is_delete` = ?)",
                "bindings": [
                    0
                ],
                "time": 0.25
            },
            {
                "query": "select `wm_course_user`.`id`, `wm_course_user`.`user_id`, `wm_course_user`.`course_id`, `wm_course_user`.`created_at` from `wm_course_user` where (`wm_course_user`.`is_delete` = ?) order by `wm_course_user`.`id` desc limit 20 offset 0",
                "bindings": [
                    0
                ],
                "time": 0.27
            },
            {
                "query": "select * from `wm_user` where `wm_user`.`id` = ? limit 1",
                "bindings": [
                    1643
                ],
                "time": 0.44
            },
            {
                "query": "select * from `wm_user` where `wm_user`.`id` = ? limit 1",
                "bindings": [
                    2
                ],
                "time": 0.37
            }

    看到每个关联都要查询一次数据库,这就是所谓的N+1的查询问题。

    DB::enableQueryLog();
            $filter = [];
            $filter['course_id'] = $course_id;
    
    //        $filter['with']['user'] = [];
            $items = CourseUser::items($filter);
            foreach($items as $value){
                if($value->user_id == 2){
                    var_dump($value->user->name);
                }
            }
            $query =DB::getQueryLog();
            return self::success($query);

    执行语句

    {
                "query": "select count(*) as aggregate from `wm_course_user` where (`wm_course_user`.`is_delete` = ?)",
                "bindings": [
                    0
                ],
                "time": 0.28
            },
            {
                "query": "select `wm_course_user`.`id`, `wm_course_user`.`user_id`, `wm_course_user`.`course_id`, `wm_course_user`.`created_at` from `wm_course_user` where (`wm_course_user`.`is_delete` = ?) order by `wm_course_user`.`id` desc limit 20 offset 0",
                "bindings": [
                    0
                ],
                "time": 0.25
            },
            {
                "query": "select * from `wm_user` where `wm_user`.`id` = ? limit 1",
                "bindings": [
                    2
                ],
                "time": 0.47
            }

    如何避免N+1问题呢?使用with查询进行预加载

    DB::enableQueryLog();
    $filter = [];
    $filter['course_id'] = $course_id;
    $filter['with']['user'] = [];
    CourseUser::items($filter);
    $query =DB::getQueryLog();
    return self::success($query);

    打印出执行的sql如下

     {
                "query": "select count(*) as aggregate from `wm_course_user` where (`wm_course_user`.`is_delete` = ?)",
                "bindings": [
                    0
                ],
                "time": 0.28
            },
            {
                "query": "select `wm_course_user`.`id`, `wm_course_user`.`user_id`, `wm_course_user`.`course_id`, `wm_course_user`.`created_at` from `wm_course_user` where (`wm_course_user`.`is_delete` = ?) order by `wm_course_user`.`id` desc limit 20 offset 0",
                "bindings": [
                    0
                ],
                "time": 0.31
            },
            {
                "query": "select * from `wm_user` where `wm_user`.`id` in (2, 1643)",
                "bindings": [],
                "time": 0.43
            }

    一共查询了3次。

    当以属性方式访问 Eloquent 关联时,关联数据「懒加载」。这着直到第一次访问属性时关联数据才会被真实加载。不过 Eloquent 能在查询父模型时「预先载入」子关联。预加载可以缓解 N + 1 查询问题。

    什么时候使用懒加载,什么时候使用预加载呢?列表数据需要展示的内容使用预加载、在详情里面才需要展示的内容使用懒加载。

  • 相关阅读:
    Go语言- import 导入包的语法
    go语言学习入门篇 3-- 程序执行流程
    go语言学习入门篇 2--轻量级线程的实现
    go语言学习入门篇1---go语言的主要特性与发展
    网络传输中的各种加密算法+SSL+CA证书详解
    压测工具 jmeter入门教程及汉化修改
    Array.isArray and Object.prototype.toString.call
    trim() 方法
    回文字符串判断
    监听微信返回按钮事件
  • 原文地址:https://www.cnblogs.com/webclz/p/10932113.html
Copyright © 2011-2022 走看看