การโหลดข้อมูลล่วงหน้าและขอบเขตคำสืบค้น
ป้องกันคำสืบค้น N+1 ด้วยการโหลดข้อมูลล่วงหน้า และนำตรรกะกลับมาใช้ใหม่ด้วยขอบเขตคำสืบค้น
การโหลดข้อมูลล่วงหน้าและขอบเขตคำสืบค้น เป็นบทเรียน PHP Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน PHP Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส PHP Academy มีบทเรียนทั้งหมด 4 บทเรียน
ปัญหา N+1
การโหลดแบบขี้เกียจจะเรียกใช้คำค้นหาหนึ่งครั้งต่อโมเดลเมื่อเข้าถึงความสัมพันธ์ภายในการวนซ้ำ ซึ่งส่งผลเสียอย่างรุนแรงเมื่อระบบมีขนาดใหญ่
<?php
$posts = Post::all(); // 1 query
foreach ($posts as $post) {
echo $post->author->name; // 1 query per post = N+1 total!
}การโหลดล่วงหน้าด้วย with()
แก้ปัญหา N+1 ด้วยการโหลดความสัมพันธ์ล่วงหน้าตั้งแต่ต้น โดยใช้คำค้นหาเพิ่มเติมเพียงครั้งเดียว
<?php
$posts = Post::with("author")->get(); // 2 queries total
foreach ($posts as $post) {
echo $post->author->name; // no extra query
}การโหลดความสัมพันธ์หลายรายการล่วงหน้า
โหลดความสัมพันธ์หลายรายการพร้อมกัน
<?php
$posts = Post::with(["author", "tags", "comments"])->get();การโหลดความสัมพันธ์ซ้อนกันล่วงหน้า
โหลดความสัมพันธ์ที่ซ้อนกันโดยใช้รูปแบบจุด
<?php
$posts = Post::with("comments.author")->get();
// Loads posts, their comments, and each comment's authorการโหลดล่วงหน้าพร้อมเงื่อนไข
ใช้เงื่อนไขกับความสัมพันธ์ที่โหลดล่วงหน้า
<?php
$posts = Post::with(["comments" => function ($q) {
$q->where("approved", true)->latest();
}])->get();withCount()
โหลดจำนวนของโมเดลที่เกี่ยวข้องโดยไม่ต้องโหลดโมเดลที่เกี่ยวข้องเหล่านั้นเอง
<?php
$posts = Post::withCount("comments")->get();
foreach ($posts as $post) {
echo $post->comments_count;
}การโหลดล่วงหน้าแบบขี้เกียจ (load())
โหลดความสัมพันธ์ล่วงหน้าบนคอลเลกชันที่ดึงมาแล้วด้วย load()
<?php
$posts = Post::all();
// Later, when you know you need the authors:
$posts->load("author");ขอบเขตคำค้นหาระดับส่วนกลาง
ขอบเขตระดับส่วนกลางจะเพิ่มข้อจำกัดให้กับคำค้นหาทั้งหมดของโมเดลโดยอัตโนมัติ
<?php
class PublishedScope implements \Illuminate\Database\Eloquent\Scope {
public function apply(Builder $builder, Model $model): void {
$builder->where("is_published", true);
}
}ขอบเขตคำค้นหาเฉพาะที่
ขอบเขตเฉพาะที่คือข้อจำกัดของคำค้นหาที่นำกลับมาใช้ใหม่ได้ โดยกำหนดในโมเดลเป็นเมธอดที่มีคำนำหน้า scope
<?php
class Post extends Model {
public function scopePublished(Builder $query): void {
$query->where("is_published", true);
}
public function scopeByUser(Builder $query, int $userId): void {
$query->where("user_id", $userId);
}
}
// Usage:
Post::published()->byUser(1)->latest()->get();การรวมขอบเขต
เชื่อมขอบเขตเฉพาะที่หลายรายการเพื่อให้ตรรกะของคำค้นหาอ่านง่ายและนำกลับมาใช้ใหม่ได้
<?php
$posts = Post::published()
->byUser(auth()->id())
->orderBy("created_at", "desc")
->paginate(15);การตรวจจับ N+1 ระหว่างการพัฒนา
ใช้ Laravel Debugbar หรือเรียกใช้ DB::enableQueryLog() เพื่อตรวจจับจำนวนคำค้นหาที่ไม่คาดคิดระหว่างการพัฒนา
สรุป
ใช้ with() เพื่อโหลดความสัมพันธ์ล่วงหน้าและกำจัดคำค้นหาแบบ N+1 ใช้ withCount() สำหรับนับจำนวน และกำหนดขอบเขตเฉพาะที่เพื่อสร้างข้อจำกัดของคำค้นหาที่นำกลับมาใช้ใหม่ได้และอ่านง่าย
ตรวจสอบความเข้าใจ
เมธอดใดใช้โหลดโมเดลที่เกี่ยวข้องล่วงหน้าเพื่อแก้ปัญหา N+1
คำถามที่พบบ่อย
บทเรียน “การโหลดข้อมูลล่วงหน้าและขอบเขตคำสืบค้น” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การโหลดข้อมูลล่วงหน้าและขอบเขตคำสืบค้น” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส PHP Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส PHP Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การโหลดข้อมูลล่วงหน้าและขอบเขตคำสืบค้น”
ป้องกันคำสืบค้น N+1 ด้วยการโหลดข้อมูลล่วงหน้า และนำตรรกะกลับมาใช้ใหม่ด้วยขอบเขตคำสืบค้น คุณปฏิบัติ PHP Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน PHP Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน PHP Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การโหลดข้อมูลล่วงหน้าและขอบเขตคำสืบค้น” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน PHP Academy นี้ได้ไหม
ได้ บทเรียน PHP Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- โมเดล Eloquent และการย้ายโครงสร้างฐานข้อมูล
- CRUD ด้วย Eloquent
- ความสัมพันธ์ของ Eloquent
- การโหลดข้อมูลล่วงหน้าและขอบเขตคำสืบค้น