0Pricing
PHP Academy · บทเรียน

การโหลดข้อมูลล่วงหน้าและขอบเขตคำสืบค้น

ป้องกันคำสืบค้น 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. โมเดล Eloquent และการย้ายโครงสร้างฐานข้อมูล
  2. CRUD ด้วย Eloquent
  3. ความสัมพันธ์ของ Eloquent
  4. การโหลดข้อมูลล่วงหน้าและขอบเขตคำสืบค้น
← กลับไปที่ PHP Academy