简体   繁体   中英

Laravel Eloquent: Reduce number of queries

Let's say I have 250 users in users table and each user has one or many books, and each book has one or many chapters. Now I would like to print the user names, with their book names.

Controller:

$users = User::all();

in blade:

@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

Now to overcome the n+1 problem, the query should be

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

Now the # of queries are only 2.

I want to print the book names with number of chapters like this-> BookName(# of chapters). So in my blade

@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

so for 750 books with 1500 chapters the # of queries are about 752 and it increases if chapter number increases.

Is there any better Eloquent way to reduce it or should I go for raw SQL queries?

From the Eloquent Documentation :

Nested Eager Loading

To eager load nested relationships, you may use "dot" syntax. For example, let's eager load all of the book's authors and all of the author's personal contacts in one Eloquent statement:

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

In your case, you can retrieve the nested relationships you need with the following:

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

You don't need to load all chapters data and then manually count each collection. Use withCount() instead:

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

If you want to count the number of results from a relationship without actually loading them you may use the withCount method, which will place a {relation}_count column on your resulting models.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM