Tối ưu các truy vấn Eloquent để giảm mức tiêu thụ bộ nhớ

Đăng bởi:

Trần Hậu Kiên

Đăng ngày:

Mar 31, 2021

Đăng ở:

Thủ Thuật Thiết Kế

Mô tả vấn đề

Chắc chắn, Eloquent ORM là rất mạnh mẽ nhưng để có thể tận dụng tối đa nó, nó là cần thiết để thực hiện một số thực hành tốt khi truy vấn vào cơ sở dữ liệu. Ví dụ:

<?php use App\User; $users = User::all();

Tiếp theo, các truy vấn rất điển hình được hiển thị trong các web applications được sử dụng bằng Laravel:

Truy vấn tất cả các bản ghi trong bảng người dùng

<?php use App\User; # Wrong $users = User::all(); # Right $users = User::all(['id', 'name', 'email']);

Lấy tất cả các bản ghi của bảng người dùng với các bài viết của từng người dùng bằng cách sử dụng Eager Loading

<?php use App\User; # Wrong

$users = User::with('posts')->get(); # Right

$users = User::with([ 'posts' => function ($query) {

$query->select('id', 'title', 'content', 'user_id'); } ])->get(['id', 'name', 'email']);

Truy vấn tất cả các bài post với các model quan he

<?php use App\Post; # Wrong

$posts = Post::with(['images', 'tags', 'user'])->get(); # Right

$posts = Post::with([ 'tags' => function ($query) {

$query->select('id', 'name'); # Many to many },

'images' => function ($query) {

$query->select('id', 'url', 'post_id'); # One to many },

'user' => function ($query) {

$query->select('id', 'name'); # One to many } ])->get(['id', 'title', 'content', 'user_id']);

Truy vấn tất cả bài post có phân trang

<?php use App\Post; # Wrong

$posts = Post::paginate(30); # Right

$posts = Post::paginate(30, ['id', 'title', 'content', 'user_id']);

Bạn có thể invoke phương thức with trước phương thức paginate để load các model quan hệ.

Tìm kiếm một bài post

<?php use App\Post; # Wrong

$post = Post::findOrFail($id); # Right

$post = Post::findOrFail($id, ['id', 'title', 'content']);

Tìm kiếm một bài post sử dụng where

<?php use App\Post; # Wrong

$post = Post::where('id', $id)->first(); # Right

$post = Post::where('id', $id)->first(['id', 'title', 'content']);

Sử dụng mệnh đề Where bạn có thể tìm kiếm nhiều bài viết với phương thức Get, nó sẽ trả về một tập hợp các object, trong khi các phương thức First và Find trở thành một object.

Tìm kiếm bài post của người dùng được xác thực bằng các model quan hệ

<?php use App\User; use App\Post; # Wrong

$posts = User::find(auth()->user()->id)->posts() ->with(['images', 'tags', 'user']) ->get(); # Right

$posts = User::find(auth()->user()->id)->posts() ->with([ 'tags' => function ($query) { $query->select('id', 'name'); # Many to many },

'images' => function ($query) {

$query->select('id', 'url', 'post_id'); # One to many },

'user' => function ($query) {

$query->select('id', 'name'); # One to many } ])->get(['id', 'title', 'content', 'user_id']);

Nó có thể áp dụng để tìm kiếm bất kỳ đăng ký liên quan nào đến người dùng đã được xác thực. Truy vấn nâng cao

<?php use App\Invoice; # Wrong

$invoice = Invoice::where('id', $id) ->with([ 'products', 'products.subcategory', 'products.subcategory.category', 'customer', ])->first(); # Right

$invoice = Invoice::where('id', $id) ->with([ 'products' => function ($query) {

$query->select('id', 'price', 'description', 'subcategory_id') ->withPivot('quantity', 'subvalue', 'taxes', 'value'); },

'products.subcategory' => function ($query) {

$query->select('id', 'name', 'category_id'); },

'products.subcategory.category' => function ($query) {

$query->select('id', 'name'); }, 'customer' => function ($query) {

$query->select('id', 'name', 'lastname', 'dni', 'addrress', 'phone'); }, ])->first(['id', 'subvalue', 'taxes', 'value', 'customer_id']);

Trên đây là môi trường thử nghiệm ở local nên sự khác biệt không cao lắm. Tuy nhiên, trong các ứng dụng thực tế, các tiêu thụ bộ nhớ này cao hơn nhiều và có thể quan sát thấy hiệu suất của server sẽ giảm. Nếu những kết quả này được nhân với số lượng người dùng đáng kể có thể truy cập vào ứng dụng, vấn đề sẽ trở nên đáng chú ý hơn.

Đây chỉ là một số cách tối ưu hóa truy vấn để có thể xử lý vấn đề về bộ nhớ, còn nhiều cách tối ưu truy vấn để dự án của bạn có thể hoàn thiện hơn. Cùng tìm hiểu ở phần sau nhé. Chúc các bạn thành công với những dự án sắp tới!

Tham khảo: https://viblo.asia/p/toi-uu-hoa-cac-truy-van-eloquent-de-giam-muc-tieu-thu-bo-nho-4P856Pr1ZY3

 

 

 

 

default_image
Tác giả: Trần Hậu Kiên
ADMIN

Bình luận

Để lại bình luận

Email và số điện thoại sẽ không được công khai. Những trường bắt buộc được đánh dấu *

Repository deleted Your repository has remove
Loading
Bạn cần hỗ trợ?