php - 在同一个对象中获取一个线程及其最新的帖子,latest() 会产生巨大的开销

标签 php mysql laravel laravel-5

假设我在名为 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/

相关文章:

php - laravel 的 nginx 配置

php - PDO fetch 在 PHP 中总是返回 false

php - 使用 ajax 向我的服务器发送了一个对象,似乎无法使用 php 获取数据

php - paypal IPN的ssl地址ssl是什么

mysql - 如何让 MySQL 表相互更新?

mysql - 如何进行 if 和 else mysql 查询

php - Blueprint 类的 timestamp() 和 dateTime() 方法之间的区别

php - 获取开始日期到结束日期之间的日期,以 php 月份明智计数

mysql - java.sql.ResultSet.next() 说明

mysql - 如何获取当前年份的每月金额总和并将其显示在 consoleTv 条形图中