Chúng ta thường nghe cụm từ "Eager Loading" và "Lazy Loading" trong Laravel. nhưng có lẽ một số người vẫn không biết điều đó thực sự đại diện cho điều gì
Lazy Loading có nghĩa là gì?
Tôi đã làm việc với nhiều dự án được phát triển bởi một số nhà phát triển khác và các vấn đề phổ biến trong mã tôi thấy chúng tôi Truy vấn tải chậm ở mọi nơi
Để hiểu nó dễ dàng hơn, hãy lấy một ví dụ đơn giản
Giả sử Có mô hình
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
7 và Mô hình 1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
8Vì vậy, về cơ bản
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
9Vì vậy, giả sử chúng tôi đang tìm nạp 10 bài đăng và bây giờ chúng tôi muốn nhận xét của mỗi bài đăng. những gì chúng ta sẽ làm là
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
0 [TẢI LƯNG]Lazy loading gây ra các vấn đề về truy vấn N+1 vì mỗi lần chúng tôi tìm nạp nhận xét của từng bài đăng và nó cũng sẽ chặn việc thực thi trong khi các truy vấn của nó từ DB
Eager Loading có nghĩa là gì?
Eager loading rất hữu ích khi chúng ta làm việc với các dự án quy mô lớn. nó tiết kiệm rất nhiều thời gian thực hiện và thậm chí cả các truy vấn DB. ]
Lấy ví dụ trên để hiểu Eager loading
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
1 1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
2 [ĐANG TẢI HẤP DẪN]ở đây khi chúng tôi truy xuất các bài đăng vào thời điểm đó, chúng tôi cũng đang tìm nạp các nhận xét của nó trên cùng một truy vấn. vì vậy khi chúng tôi thực hiện
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
2, nó sẽ không thực hiện lại truy vấn vào DB hoặc thậm chí không chặn thực thi vì các nhận xét đã có sẵn trong phiên bản mô hình Trong một bài viết trước, tôi đã nói về những cải thiện hiệu suất mà bạn có thể đạt được bằng cách sử dụng "eager loading" trong các truy vấn cơ sở dữ liệu Laravel của mình. Ai chưa đọc thì click vào đây để đọc nhanh
Eager Loading là gì?
Khi bạn đang tìm nạp bất kỳ mô hình nào từ cơ sở dữ liệu và sau đó thực hiện bất kỳ loại xử lý nào trên các mối quan hệ của mô hình, điều quan trọng là bạn phải sử dụng tải háo hức. Eager loading cực kỳ đơn giản khi sử dụng Laravel và về cơ bản giúp bạn không gặp phải sự cố N+1 với dữ liệu của mình. Sự cố này xảy ra do thực hiện N+1 truy vấn tới cơ sở dữ liệu, trong đó N là số mục được tìm nạp từ cơ sở dữ liệu. Để giải thích điều này rõ hơn và cung cấp cho nó một số ngữ cảnh, hãy xem ví dụ bên dưới
Hãy tưởng tượng rằng bạn có hai mô hình [
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
4 và 1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
5] với mối quan hệ một đối một giữa chúng. Bây giờ, hãy tưởng tượng rằng bạn có 100 nhận xét và bạn muốn lặp qua từng nhận xét và xuất tên tác giảNếu không tải háo hức, mã của bạn có thể trông như thế này
1$comments = Comment::all[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
Đoạn mã trên sẽ dẫn đến 101 truy vấn cơ sở dữ liệu vì kết quả là "tải chậm". Truy vấn đầu tiên sẽ là lấy tất cả các bình luận. Một trăm truy vấn khác sẽ đến từ việc lấy tên tác giả trong mỗi lần lặp của vòng lặp. Rõ ràng, điều này có thể gây ra các vấn đề về hiệu suất và làm chậm ứng dụng của bạn. Vì vậy, làm thế nào chúng ta sẽ cải thiện điều này?
Bằng cách sử dụng tải háo hức, chúng tôi có thể thay đổi mã để nói
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
Như bạn có thể thấy, mã này trông gần như giống nhau và vẫn có thể đọc được. Bằng cách thêm
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
0, thao tác này sẽ tìm nạp tất cả các nhận xét và sau đó thực hiện một truy vấn khác để tìm nạp tác giả cùng một lúc. Vì vậy, điều này có nghĩa là chúng tôi sẽ cắt giảm truy vấn từ 101 xuống còn 2Để biết thêm thông tin, hãy xem tài liệu về Laravel về tải háo hức
Cách buộc Laravel sử dụng Eager Loading
Một tính năng mới [được thêm bởi Mohamed Said] gần đây đã được hợp nhất vào cơ sở mã Laravel cho phép bạn ngăn quá trình tải chậm diễn ra. Tính năng này cực kỳ hữu ích vì nó sẽ giúp đảm bảo rằng các mối quan hệ được tải háo hức. Do đó, nó có thể sẽ giúp chúng tôi cải thiện hiệu suất và giảm số lượng truy vấn được thực hiện đối với cơ sở dữ liệu như trong ví dụ trên
Thật đơn giản để ngăn chặn lazy loading. Tất cả những gì chúng ta cần làm là thêm dòng sau vào phương thức
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
1 của 1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
2 1Model::preventLazyLoading[];
Vì vậy, trong
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
2 của chúng tôi, nó sẽ giống như thế này 3use Illuminate\Support\ServiceProvider;
5class AppServiceProvider extends ServiceProvider
7 public function boot[]: void
10 Model::preventLazyLoading[];
Cho phép Eager Loading trong môi trường sản xuất
Có thể bạn chỉ muốn bật tính năng này khi ở trong môi trường phát triển cục bộ của mình. Bằng cách đó, nó có thể cảnh báo bạn về những vị trí trong mã của bạn đang sử dụng lazy loading trong khi xây dựng các tính năng mới, nhưng không làm hỏng hoàn toàn trang web sản xuất của bạn. Vì lý do này, phương thức
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
4 chấp nhận một đối số boolean, vì vậy chúng ta có thể sử dụng dòng sau 1Model::preventLazyLoading[! app[]->isProduction[]];
Vì vậy, trong
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
2 của chúng tôi, nó có thể trông như thế này 1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
1Bằng cách này, tính năng này sẽ bị tắt nếu
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
6 của bạn là 1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
7 để bất kỳ truy vấn tải chậm nào trượt qua đều không gây ra ngoại lệ trên trang web của bạnĐiều gì xảy ra nếu chúng ta cố gắng Lazy Load?
Nếu chúng tôi đã bật tính năng này trong nhà cung cấp dịch vụ của mình và chúng tôi cố gắng tải chậm một mối quan hệ trên một mô hình, một ngoại lệ
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
8 sẽ được đưa raĐể cung cấp cho điều này một chút ngữ cảnh, hãy sử dụng các ví dụ về mô hình
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
4 và 1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
5 của chúng tôi ở trên. Giả sử rằng chúng tôi đã bật tính năng nàyĐoạn mã sau sẽ đưa ra một ngoại lệ
1$comments = Comment::all[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
Tuy nhiên, đoạn mã sau sẽ không đưa ra một ngoại lệ
1$comments = Comment::with[‘authors’]->get[];
3foreach [$comments as $comment ] {
4 print_r[$comment->author->name];
Phần kết luận
Theo ý kiến cá nhân của tôi, tôi nghĩ rằng tính năng này sẽ thực sự hữu ích và nó có thể sẽ giúp khuyến khích các thực hành truy vấn cơ sở dữ liệu và mô hình tốt hơn. Tôi có cảm giác rằng đây sẽ là một tính năng mà tôi sử dụng hàng ngày và có thể sẽ nghĩ "Tôi đã sử dụng như thế nào để tồn tại nếu không có tính năng này?"
Tôi hy vọng rằng bạn tìm thấy bài viết ngắn này hữu ích mặc dù. Nếu đó là loại điều mà bạn muốn nghe thêm, vui lòng đăng ký nhận bản tin của tôi bên dưới. Bạn sẽ nhận được thông báo mỗi khi tôi đăng một bài viết mới về thế giới Laravel. 🚀