Laravel Eloquent:减少查询次数

时间:2017-01-09 04:41:29

标签: php mysql laravel eloquent

我们说users表中有250个用户,每个用户都有一本或多本书,每本书都有一个或多个章节。现在我想打印用户名和他们的书名。

控制器:

$users = User::all();
刀片中的

@foreach($users as $user)
  <tr>
      <td>{{ $user->id }}</td>
      <td>{{ $user->name }}</td>
      <td>
        @foreach($user->books as $book)
          {{ $book->name }},
          @endforeach
      </td>
  </tr>
@endforeach

# of queries 252

现在要克服n + 1问题,查询应该是

$users = User::with('books')->get();

现在查询数量只有2个。

我想用这样的章节打印书名 - &gt; BookName(章节数)。所以在我的刀片中

@foreach($users as $user)
      <tr>
          <td>{{ $user->id }}</td>
          <td>{{ $user->name }}</td>
          <td>
            @foreach($user->books as $book)
              {{ $book->name }} ({{ $book->chapters->count() }}),
              @endforeach
          </td>
      </tr>
    @endforeach

因此,对于包含1500章的750本书,查询数量约为752,如果章节数增加则会增加。

有没有更好的Eloquent方法来减少它,还是应该进行原始SQL查询?

2 个答案:

答案 0 :(得分:5)

From the Eloquent Documentation

  

嵌套预先加载

     

要急切加载嵌套关系,您可以使用“dot”语法。例如,让我们在一个Eloquent声明中急切地加载本书的所有作者和作者的所有个人联系人:

     

$books = App\Book::with('author.contacts')->get();

在您的情况下,您可以使用以下内容检索所需的嵌套关系:

User::with('books.chapters')->get();

答案 1 :(得分:4)

您不需要加载所有章节数据,然后手动计算每个集合。请改用withCount()

$users = User::with('books')->withCount('chapters')->get();
  

如果您想要计算关系中的结果数而不实际加载它们,您可以使用withCount方法,该方法会在结果模型上放置{relation} _count列。