Laravel N + 1 query ပြသာနာ

ayarhlaine

Ayar Hlaine

Posted on January 3, 2021

Laravel N + 1 query ပြသာနာ

N + 1 query ပြသာနာကတော့ လက်ရှိ developer တွေတော်တောများများဖြစ်လေ့ဖြစ်ထရှိတဲ့ပြသာနာပါ။

ဘယ်အချိန်မှာဖြစ်တက်တာလဲ?

ပုံမှန်အားဖြင့်တော့ data list တွေကို ပြန်ပြတဲ့နေရာမျိုးတွေမှာဖြစ်လေ့ဖြစ်ထာရှိပါတယ်။

ဘယ်လိုမျိုးဖြစ်တာလဲ?

ဥပမာ ကိုယ့်ရဲ့ database ထဲမှာ record 100 ရှိတယ်။ ကိုယ်ကသာမာန် data လေးထုတ်ပြပေမဲ့ database ကို query သွားဆွဲတာက 101 (100 records + 1 times) ကြိမ်ဖြစ်နေတာမျိုးပါ။

အသေးစိတ်ရှင်းလင်းချက်

Laravel မှာကျနော်တို့က ORM ကိုသုံးပြီးတော့ relationship တွေကိုလိုအပ်သလို့စီမံအသုံးပြု့ကြပါတယ်။ ဒီနေရာမှာ Eloquent ORM Relationship တွေဟာ lazy loading တွေဖြစ်တယ်ဆိုတာကိုသတိ့ပြု့ကြရမှာပါ။
ဥပမာ ......

Book Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * Get the author that wrote the book.
     */
    public function author()
    {
        return $this->belongsTo(Author::class);
    }
}
Enter fullscreen mode Exit fullscreen mode

Author Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Author extends Model
{

}
Enter fullscreen mode Exit fullscreen mode

ဒီနေရာမှာ စာအုပ်စာရင်းရယ်၊ ရေးတဲ့သူတွေကို တွဲပြချင်တဲ့ အခါမှာ အောက်ပါအတိုင်းရေးလေ့ရှိ့ပါတယ်။

use App\Models\Book;

$books = Book::all();

foreach ($books as $book) {
    echo $book->author->name;
}
Enter fullscreen mode Exit fullscreen mode

အဲလိုရေးတဲ့အခါ ....
Book::all() လုပ်တဲ့အချိန်မှာ query တစ်ကြိမ်အလုပ်လုပ်ရပါတယ်။
loop ပတ်ရင်း $book->author ဆိုတဲ့အချိန်မှာ query တစ်ကြိမ်စီလုပ်ရပါတယ်။
အဲတော့ ကျနော်တို့ database ထဲမှာ စာအုပ်ပေါင်း 100 ရှိတယ်ဆိုရင် စုစုပေါင်း 101 ကြိမ် query ဆွဲရသလိုဖြစ်နေတာပါ။ ဒါကိုပဲ N + 1 Query Problem လိုခေါ်ကြတာပါ။

ဘယ်လိုရှောင်ရှားမလဲ?

ဒါကို ရှောင်ရှားဖို့ဆိုရင်တော့ Laravel မှာဆိုရင်တော့တော်တော်လေးလွယ်ပါတယ်။
Laravel မှာတော့ ဒါကို ရှောင်ရှားဖို့အတွက် Eager Loading ကိုအသုံးပြု့ပါတယ်။
အထက်ပါဥပမာကို Eager Loading နဲ့ပြန်ရေးကြည့်မယ်ဆိုရင် ...

use App\Models\Book;

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

foreach ($books as $book) {
    echo $book->author->name;
}
Enter fullscreen mode Exit fullscreen mode

ဒီနေရာမှာ with('author') ဆိုတဲ့အပိုင်းလေးက Eager Loading ကိုအသုံးပြု့ထားတဲအပိုင်းပါ။ ဆိုလိုတာကတော့ စာအုပ် information တွဲဆွဲယူရင်း author information တွေပါ တစ်ပါတည်းယူခဲတဲ့သဘောပါ။ အဲဒီလို Eager Loading နဲရေးလိုက်တဲအတွက်ကြောင့် Query 2 ကြိမ်ပဲအလုပ်လုပ်ပါတော့တယ်။

ပထမတစ်ခု့က စာအုပ်စာရင်းဆွဲထုတ်ဖို့

select * from books
Enter fullscreen mode Exit fullscreen mode

ဒုတိယတစ်ခု့က သက်ဆိုင်ရာ စာရေးသူအားလုံးကို ထုတ်ဖို့

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

အထက်ပါနည်းနဲ့ Eager Loading ကိုသုံးပြီး N + 1 ပြသာနာကိုရှောင်ရှားကြပါတယ်။
ဒီပြသာနာက Laravel မှာတင်မဟုတ်ပဲ တစ်ခြား frameworks, languages, library မှာလည်းရှိနေမှာပါပဲ။ အထူးဂရုပြု့ရှောင်းရှားကြရမှာဖြစ်ပါတယ်။

References

Laravel မှာ Eager Loading နဲ့ N + 1 ပြသာနာ အကြောင်အသေးစိတ် ဖတ်ချင်ရင်တော့ ဒီမှာ ရပါတယ်။


Buy Me a Coffee at ko-fi.com

အားလုံးကိုကျေးဇူးတင်ပါတယ်။
ဆက်လက်ကြိုးစားပါအုံးမည်။

A.Y.H

💖 💪 🙅 🚩
ayarhlaine
Ayar Hlaine

Posted on January 3, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related