ทำไม Laravel ถึง "คิดนาน" เกินไป?
ลองนึกภาพว่าคุณเปิดร้านอาหาร แต่ทุกครั้งที่ลูกค้าสั่งข้าว พ่อครัวต้องไปอ่านสูตรอาหารใหม่ทุกครั้ง นั่นคือสิ่งที่เกิดขึ้นกับ Laravel ที่ไม่ได้ optimize — Framework กำลังทำงานซ้ำๆ ที่ไม่จำเป็นในทุก Request
ปัญหาหลักที่ทำให้ Laravel Application ช้าในสภาพแวดล้อม Production มักจะมาจาก 3 แหล่ง ได้แก่ N+1 Query Problem, Missing Database Index, และ Framework overhead ที่ไม่จำเป็น บทความนี้จะพาไปแก้ทีละจุด พร้อม Code Example ที่ใช้ได้จริง
เหมาะสำหรับใคร? นักพัฒนาที่ใช้ Laravel (หรือ CodeIgniter 4) ที่เริ่มพบปัญหา Application ช้าเมื่อมี User มากขึ้น หรืออยากเตรียมรับมือตั้งแต่ต้น
1. ปัญหา N+1 Query — ศัตรูเงียบของ Database
N+1 Problem คือปัญหาที่พบบ่อยที่สุดใน ORM ทุกตัว รวมถึง Laravel Eloquent เกิดขึ้นเมื่อโค้ดดึงข้อมูล Parent แล้ว Loop ดึง Child ทีละรายการ
❌ โค้ดที่มีปัญหา (N+1)
✅ แก้ด้วย Eager Loading
✅ Nested Eager Loading (Relationship ซ้อนกัน)
ติดตั้ง barryvdh/laravel-debugbar หรือ spatie/laravel-query-detector เพื่อจับ N+1 Query ใน Development โดยอัตโนมัติ
2. Database Indexing — ทำ Query ให้เร็วขึ้น 100x
Index คือ "สารบัญ" ของตาราง Database ถ้าไม่มี Index MySQL ต้องสแกนทุก Row เพื่อหาข้อมูลที่ต้องการ (Full Table Scan) ซึ่งช้ามากเมื่อข้อมูลมีหลายล้านแถว
เพิ่ม Index ผ่าน Laravel Migration
เพิ่ม Index ให้ตารางที่มีอยู่แล้ว
ใส่ Index มากเกินไปก็ไม่ดี เพราะ INSERT/UPDATE จะช้าลง ใส่เฉพาะ Column ที่ใช้ใน WHERE, ORDER BY, JOIN เท่านั้น
3. Select เฉพาะ Column ที่ต้องการ — อย่าดึง * ทุกครั้ง
การใช้ Post::all() หรือ select * จะดึงข้อมูลทุก Column แม้แต่ Column ที่หนัก เช่น content หรือ metadata ที่ไม่ได้ใช้
4. Route & Config Cache — เคล็ดลับ 30ms ที่คนมองข้าม
โดย Default ทุกครั้งที่มี HTTP Request เข้ามา Laravel จะทำการ compile Regex Pattern ของทุก Route และสร้าง Routing Table ใน Memory ใหม่ทุกครั้ง ถ้ามี 200 Routes และ Request 1 ล้านครั้งต่อวัน นั่นหมายถึง CPU เสียไปกว่า 8 ชั่วโมง เพียงเพื่อหาว่าต้องเรียก Controller ไหน
คำสั่ง Optimize สำหรับ Production
ตัวอย่าง Deployment Script (CI/CD)
อย่าลืม optimize:clear ก่อน Deploy ทุกครั้ง ถ้า Cache Route เก่าค้างอยู่ Route ใหม่จะไม่ทำงาน จนกว่าจะ Clear Cache
5. Query Caching ด้วย Laravel Cache
สำหรับข้อมูลที่ไม่เปลี่ยนบ่อย เช่น Category, Setting, หรือ Dashboard Stats การ Cache ผลลัพธ์ Query ไว้ใน Redis/Memcached จะลด Database Load ได้มหาศาล
6. สรุปเปรียบเทียบ: ก่อน vs หลัง Optimize
7. Production Checklist ก่อน Go-Live
- 01รัน
php artisan telescope:installหรือ DebugBar ใน Dev เพื่อหา N+1 Queries - 02ตรวจ Migration ทุกตัร — มี Index บน Column ที่ใช้ใน
WHEREและJOINครบหรือยัง - 03เปลี่ยน
APP_ENV=productionและAPP_DEBUG=falseใน.env - 04รัน
php artisan optimizeใน Deployment Script เสมอ - 05ตั้งค่า Redis เป็น Cache Driver และใช้
Cache::remember()สำหรับ Query ที่ดึงบ่อย - 06ใช้
paginate()แทนget()เสมอสำหรับ List ข้อมูล
สรุป
การ Optimize Laravel Application ไม่ได้ซับซ้อนอย่างที่คิด เพียงแค่เข้าใจต้นเหตุของปัญหา และใช้ Tool ที่ Framework มีให้อยู่แล้ว Techniques ที่พูดถึงในบทความนี้สามารถ ลด Query จาก 100+ เหลือ 2, ลด Routing Overhead ลง 15 เท่า และลด Database Load ได้มากกว่า 90%
จุดเริ่มต้นที่ดีที่สุดคือ หา N+1 Query ก่อน ติดตั้ง DebugBar รัน Application แล้วดูว่ามี Query ซ้ำกี่ตัว จากนั้นค่อยๆ ใส่ with(), เพิ่ม Index, และสุดท้ายรัน php artisan optimize ก่อน Deploy
แค่นี้ Application ของคุณก็พร้อมรับ Traffic หนักๆ ได้แล้ว 🚀

ความคิดเห็น
แสดงความคิดเห็น