Ayar Hlaine
Posted on January 3, 2021
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);
}
}
Author Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Author extends Model
{
}
ဒီနေရာမှာ စာအုပ်စာရင်းရယ်၊ ရေးတဲ့သူတွေကို တွဲပြချင်တဲ့ အခါမှာ အောက်ပါအတိုင်းရေးလေ့ရှိ့ပါတယ်။
use App\Models\Book;
$books = Book::all();
foreach ($books as $book) {
echo $book->author->name;
}
အဲလိုရေးတဲ့အခါ ....
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;
}
ဒီနေရာမှာ with('author')
ဆိုတဲ့အပိုင်းလေးက Eager Loading ကိုအသုံးပြု့ထားတဲအပိုင်းပါ။ ဆိုလိုတာကတော့ စာအုပ် information တွဲဆွဲယူရင်း author information တွေပါ တစ်ပါတည်းယူခဲတဲ့သဘောပါ။ အဲဒီလို Eager Loading နဲရေးလိုက်တဲအတွက်ကြောင့် Query 2 ကြိမ်ပဲအလုပ်လုပ်ပါတော့တယ်။
ပထမတစ်ခု့က စာအုပ်စာရင်းဆွဲထုတ်ဖို့
select * from books
ဒုတိယတစ်ခု့က သက်ဆိုင်ရာ စာရေးသူအားလုံးကို ထုတ်ဖို့
select * from authors where id in (1, 2, 3, 4, 5, ...)
အထက်ပါနည်းနဲ့ Eager Loading ကိုသုံးပြီး N + 1 ပြသာနာကိုရှောင်ရှားကြပါတယ်။
ဒီပြသာနာက Laravel မှာတင်မဟုတ်ပဲ တစ်ခြား frameworks, languages, library မှာလည်းရှိနေမှာပါပဲ။ အထူးဂရုပြု့ရှောင်းရှားကြရမှာဖြစ်ပါတယ်။
References
Laravel မှာ Eager Loading နဲ့ N + 1 ပြသာနာ အကြောင်အသေးစိတ် ဖတ်ချင်ရင်တော့ ဒီမှာ ရပါတယ်။
အားလုံးကိုကျေးဇူးတင်ပါတယ်။
ဆက်လက်ကြိုးစားပါအုံးမည်။
A.Y.H
Posted on January 3, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.