首页 > 解决方案 > Laravel - 多少查询太多了?

问题描述

我有一个 laravel 网站,其中列出了类似于 reddit 的“提交”。我使用这个例子来更容易理解这个问题。

在此处输入图像描述 例如,当用户访问主页时,他会看到列出的 30 个提交。

每次提交都代表了很多信息。当然有来自提交本身的信息,比如标题等等。但是有“保存”之类的东西。对于每个提交,必须有一个查询来查看该用户是否尚未保存提交,否则它将显示“未保存”。

刀:

@if (!Auth::user()->hasSavedSubmission($submission))
    <a href="{{ route('save.submission', ['ID' => $submission->id, 'token' => $submission->token]) }}">Save</a>
@else
    <a href="{{ route('unsave.submission', ['ID' => $submission->id, 'token' => $submission->token]) }}">Unsave</a>                     
@endif

用户模型:

 public function hasSavedSubmission(Submission $submission) {
    return (bool) $submission->savedSubmissions->where('user_id', $this->id)->count();
}   

然后需要查询。但不仅仅是hasSavedSubmission,还有一个查询来查看用户是否赞成/反对提交,或者他们是否订阅了该子等等。

在评论页面上变得更糟。假设我加载了一个包含 200 条评论的评论页面。好吧,要查看您是否保存了评论或对评论进行了投票,每条评论有 2 个查询,总共有 400 个查询。

这是正常的吗?这是一种好的做法,还是我应该以某种方式优化它以减少查询,以及如何?

标签: phplaravel

解决方案


很多查询本身并不错,但是在您的情况下,可以通过调整查询数据库的方式来大大减少它们。目前,您分别查询每个提交的已保存提交,您可以对其进行更改,以便仅在一个查询中检索用户的所有已保存提交。

例如,您可以在控制器中执行以下操作:

$query = SavedSubmissions::where('user_id', Auth::user()->id);
$submissionsForUser = $query->get('id'); // only load columns you'll need also saves a bit
// Pass $submissionsForUser to your blade template

在您的刀片模板中

@if (!submissionsForUser->contains($submission->id)
    <a href="{{ route('save.submission', ['ID' => $submission->id, 'token' => $submission->token]) }}">Save</a>
@else
    <a href="{{ route('unsave.submission', ['ID' => $submission->id, 'token' => $submission->token]) }}">Unsave</a>                     
@endif

或者,您可以移动此逻辑以检索User模型的提交,但这不是很干净。

减少查询量的其他方法如下:

  • 分页评论数量
  • 延迟加载评论(仅显示前几个,带有“更多”按钮)
  • 调整您的数据库架构,以便您拥有特定视图的非规范化数据(例如,1 个表包含 1 个视图的所有数据)

推荐阅读