为什么 eloquent 在预先加载中分隔查询?

Why eloquent separates queries in eager loading?

例如我有两个查询:

return $this->model->where('closed_at', null)
            ->whereHas('users', function ($query) {
                $query->where('id', '=', auth()->user()->id);
            })         
            ->with(['product:id,title', 'in_works' => function ($query) {
                $query->where('user_id', '=', auth()->user()->id);
            }])
           ->get();

它运行良好,return 1 次查询与连接(急切加载):

select * from `order` where `closed_at` is null and exists (select * from `user` inner join `user_order` on `user`.`id` = `user_order`.`user_id` where `order`.`id` = `user_order`.`order_id` and `id` = ?)

类似查询

return $this->model->where('closed_at', null)
            ->with(['product:id,title', 'in_works' => function ($query) {
                $query->where('closed_at', '=', null);
            }])->get();

return 3 个查询,为什么?

select * from `order` where `closed_at` is null
select `id`, `title` from `product` where `product`.`id` in (1, 2)
select * from `in_work` where `in_work`.`order_id` in (1, 2) and `closed_at` is null

通过预先加载(即使用 with)添加到模型的每个关系都通过附加查询进行查询。

这是您拥有的:

  1. 模型查询
select * from `order` where `closed_at` is null -- Model 
  1. product:id,title查询
select `id`, `title` from `product` where `product`.`id` in (1, 2)
  1. in_works查询
select * from `in_work` where `in_work`.`order_id` in (1, 2) and `closed_at` is null

请注意,在情况 (2) 和 (3) 中,(1,2) 对应于从第一个查询中获得的 order 的标识符。

whereHas 将进一步细化原始模型查询,从而影响返回的总结果。在您的情况下,以下是 whereHas('users',...) 查询的结果:

select * from `order` where `closed_at` is null and exists (select * from `user` inner join `user_order` on `user`.`id` = `user_order`.`user_id` where `order`.`id` = `user_order`.`order_id` and `id` = ?)

当模型查询实际上没有产生任何结果时,实际上没有执行任何关系查询,这就是本例中发生的情况。