假设我在名为 Thread.php 的模型中有这个:
public function post()
{
return $this->hasMany('App\Post');
}
public function latestPost()
{
return $this->hasOne('App\Post')->latest('id');
}
我有一个页面显示所有线程及其最新帖子。为此,我做了类似
all_threads = Thread::with('latestPost')->get();
它执行以下查询:
select * from `posts` where `posts`.`thread_id` in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10') order by `id` desc
它可以工作,但是 latestPost()
正在为每个线程抓取表中的所有帖子,然后返回最新的帖子。这会产生数千个不必要的对象,而且开销已经很高。
理想的情况是只获取最新的 Post
记录,但我不确定如何使用 Eloquent 来做到这一点。
我试过以下方法:
return $this->hasOne('App\Post')->orderBy('id', 'desc')->limit(1);
// or
return $this->hasOne('App\Post')->latest('id')->take(1);
但是只有最后一个 Thread 对象带有 latestPost 记录。如何在仍然使用 Eloquent 的同时优化此查询?
谢谢
最佳答案
您可以尝试在 thread_id
上添加 group by
以限制每个线程返回 1 条记录。
以posts
关系为例:
$threads = Thread::with(['posts' => function ($q) {
$q->groupBy('thread_id');
})->get();
预加载的查询日志:
"select * from "posts" where "posts"."thread_id" in (?) group by "thread_id""
如果您通过 DB::select
运行该查询,它应该只为每个 thread_id
返回 1 条记录。这意味着它不必混合不需要的模型来匹配每个父项 1 个,因为它开始时每个父项最多只有 1 个。
关于php - 在同一个对象中获取一个线程及其最新的帖子,latest() 会产生巨大的开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48035771/