Eager Loading

https://viblo.asia/p/eloquent-relationships-in-laravel-phan-3-MJykjmxyePB

Eager Loading

Khi truy cập vào Eloquent relationship như property, các dữ liệu relationship là "lazy loaded". Điều này có nghĩa là các dữ liệu relationship không thực sự được load cho đến khi bạn truy cập vào property. Tuy nhiên, Eloquent có thể "eager load" các relationship vào thời điểm bạn truy vấn vào parent model. Eager loading làm giảm bớt các vấn đề truy vấn N+1. Để minh họa vấn đề truy vấn N+1, ta có Book model có liên quan đến Author model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * Get the author that wrote the book.
     */
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}

Bây giờ, chúng ta hãy lấý tất cả các books và author của nó:

$books = App\Book::all();

foreach ($books as $book) {
    echo $book->author->name;
}

Vòng lặp này sẽ thực hiện 1 truy vấn để lấy ra tất cả các books trên bàn, sau đó 1 truy vấn cho từng book để lấy ra author. Vì vậy, nếu chúng ta có 25 books, vòng lặp này sẽ chạy 26 truy vấn: 1 truy vấn để lấy ra các books và 25 truy vấn để lấy ra author cho các books.

Rất may, chúng ta có thể sử dụng eager loading để giảm thiểu số truy vấn này chỉ còn 2 truy vấn. Khi truy vấn, bạn có thể chỉ định các relationship được load bằng with method:

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

foreach ($books as $book) {
    echo $book->author->name;
}

Với cách này, chỉ có 2 câu truy vấn được thực thi:

select * from books

select * from authors where id in (1, 2, 3, 4, 5, ...)

Eager Loading Multiple Relationships

Đôi khi bạn có thể cần phải eager load nhiều mối quan hệ khác nhau, Để làm như vậy, chỉ cần thêm argument cho with method:

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

Nested Eager Loading

Để eager load các mối quan hệ lồng nhau, bạn có thể sử dụng dấu ".". Ví dụ, hãy eager load tất cả các author của các books và tất cả các contact của author trong 1 Eloquent statement:

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

Last updated