Eager Loading là gì? Làm sao để Query bằng Eager Loading trong Laravel? Tất cả sẽ được hé lộ trong bài viết dưới đây.

- Giới thiệu về Eager Loading
Eager Loading là một kỹ thuật tối ưu hóa trong Laravel giúp giảm số lượng truy vấn SQL khi truy xuất dữ liệu có quan hệ. Thay vì truy vấn từng bản ghi một cách riêng lẻ (Lazy Loading), Laravel sẽ tải trước tất cả dữ liệu liên quan trong một lần, giúp cải thiện hiệu suất và tránh lỗi “N+1 Query Problem”.
- Ta xét một ví dụ
Đoạn mã của Model Book:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Book extends Model
{
public function author(): BelongsTo
{
return $this->belongsTo(Author::class);
}
}
Và một đoạn mã
use App\Models\Book;
$books = Book::all();
foreach ($books as $book) {
echo $book->author->name;
}
Điều gì xảy ra khi chúng ta sử dụng đoạn mã này?
- Truy vấn đầu tiên lấy ra tất cả các bản ghi từ bảng books:
SELECT * FROM books;
- Khi gọi $book->author->name, Laravel thực hiện truy vấn bổ sung để lấy tên tác giả tương ứng với đầu sách đó:
SELECT * FROM authors WHERE id = ?;
- Nếu có 1000 đầu sách, Laravel sẽ thực hiện 1000 truy vấn bổ sung, tổng cộng 1001 truy vấn.
Nhược điểm: Khi số lượng đầu sách tăng lên, số lượng truy vấn cũng tăng theo, làm giảm hiệu suất hệ thống.
- Giải pháp với Eager Loading
Eager Loading giúp tải toàn bộ dữ liệu của mối quan hệ chỉ với một truy vấn duy nhất, giảm thiểu số lượng truy vấn không cần thiết.
Cách sử dụng Eager Loading
$books = Book::with(‘author’)->get();
foreach ($books as $book) {
echo $book->author->name;
}
Điều gì xảy ra khi sử dụng đoạn mã này?
- Truy vấn đầu tiên lấy danh sách các đầu sách:
SELECT * FROM books;
- Truy vấn thứ hai lấy tất cả tác giả liên quan trong một lần:
SELECT * FROM authors WHERE id IN (1, 2, 3, …, 100);
- Laravel ánh xạ dữ liệu đã lấy vào các đối tượng Book, giúp bạn truy xuất $book->author->name mà không cần thêm bất kỳ truy vấn SQL nào.
Lợi ích: Laravel chỉ thực hiện 2 truy vấn thay vì 1001 như trên, giúp tối ưu hiệu suất đáng kể.
- Eager Loading khác
Eager Loading nhiều quan hệ cùng lúc
Bạn có thể tải trước nhiều mối quan hệ cùng lúc bằng cách truyền một mảng vào with():
$books = Book::with([‘author’, ‘publisher’])->get();
Điều này giúp Laravel chỉ thực hiện 3 truy vấn thay vì hàng trăm truy vấn riêng lẻ.
Chọn lọc cột khi dùng Eager Loading
Để tránh lấy dữ liệu không cần thiết, bạn có thể chỉ định các cột cần lấy:
$books = Book::with(‘author:id,name’)->get();
Câu lệnh trên chỉ lấy cột id và name của bảng authors, giúp giảm tải dữ liệu không cần thiết.
- Khi nào nên sử dụng Eager Loading?
- Khi bạn cần truy xuất dữ liệu có quan hệ với số lượng lớn.
- Khi bạn gặp vấn đề N+1 Query Problem.
- Khi bạn muốn tối ưu hiệu suất truy vấn bằng cách giảm số lượng query SQL.
Lưu ý: Nếu bạn không chắc chắn có cần dữ liệu quan hệ hay không, hãy cân nhắc sử dụng Lazy Loading để tránh tải dư thừa dữ liệu.
- Kết luận
Eager Loading là một kỹ thuật quan trọng trong Laravel giúp cải thiện hiệu suất truy vấn bằng cách giảm số lượng truy vấn SQL. Sử dụng with() đúng cách giúp tránh lỗi N+1 Query Problem và tăng tốc độ tải dữ liệu, đặc biệt với các hệ thống có quy mô lớn.
Tài liệu tham khảo: https://laravel.com/docs/11.x/eloquent-relationships#lazy-eager-loading
Giảng viên Bùi Quang Ngọc
Bộ môn Công nghệ thông tin
FPT Polytechnic Hà Nội

