ปัญหา N+1 Query คือ anti-pattern ด้านประสิทธิภาพที่เกิดขึ้นเมื่อดึงข้อมูลรายการด้วย query ครั้งเดียว แล้วตามด้วยการ query แยกทีละรายการเพื่อดึงข้อมูลที่เกี่ยวข้องของแต่ละ record ส่งผลให้เกิดการเข้าถึงฐานข้อมูลทั้งหมด N+1 ครั้ง
เมื่อใช้งาน ORM (Object-Relational Mapping) หรือ query builder มักเกิดปัญหานี้โดยไม่รู้ตัว กระบวนการเป็นดังนี้
ลองพิจารณากรณีการแสดงหน้ารายการ glossary ก่อนอื่น SELECT 50 รายการจากตาราง glossaries จากนั้นดึงข้อมูลการแปลของแต่ละคำจากตาราง translations ทีละรายการ รวมแล้ว query จะรันทั้งหมด 51 ครั้ง หากจำนวนรายการเพิ่มเป็น 500 ก็จะรัน 501 ครั้ง
แม้ query แต่ละครั้งจะตอบสนองภายในไม่กี่มิลลิวินาที แต่เนื่องจากจำนวนครั้งเพิ่มขึ้นแบบ linear response time จึงแย่ลงตามสัดส่วนของปริมาณข้อมูล ในระหว่างการพัฒนาบนเครื่อง local ตารางอาจมีเพียงหลักสิบรายการ แต่ในระบบ production อาจพองตัวเป็นหลักพัน และความล่าช้าจะปรากฏให้เห็นเป็นครั้งแรกตรงนั้น — อุบัติเหตุแบบนี้ไม่ใช่เรื่องแปลก
นอกจากนี้ ในสภาพแวดล้อมที่ DB server และ application server แยกกันผ่านเครือข่าย overhead ของ round trip จะสะสมตามจำนวนครั้ง แม้ query เองจะเบา แต่ network latency กลายเป็นปัจจัยหลักที่ครอบงำประสิทธิภาพ
วิธีแก้ปัญหาที่เป็นตัวแทนแบ่งออกเป็น 2 ประเภทหลัก ได้แก่ eager loading (การโหลดล่วงหน้า) และ JOIN
| วิธีการ | ตัวอย่าง framework | ภาพรวม |
|---|---|---|
| eager loading | includes ของ Rails / select_related ของ Django / include ของ Prisma | ORM สร้าง query สำหรับดึงข้อมูลที่เกี่ยวข้องรวมกันโดยอัตโนมัติ |
| explicit JOIN | raw SQL / .select("*, children(*)") ของ Supabase | รวม parent และ child ใน query เดียวแล้วส่งคืน |
| DataLoader pattern | DataLoader ของ GraphQL / cache() ของ Next.js | รวบรวม key ภายใน request แล้วแปลงเป็น batch query |
เมื่อใช้ Supabase การใช้ประโยชน์จาก embedded query ของ PostgREST (select("*, translations(*)")) ช่วยให้ดึงข้อมูลที่เกี่ยวข้องได้ใน 1 request โดยไม่ต้องเขียน loop ในฝั่ง application
ในระหว่างการพัฒนา การตรวจสอบ query log เป็นวิธีที่มีประสิทธิภาพในการค้นหา N+1 สำหรับ PostgreSQL ให้ตั้งค่า log_min_duration_statement เป็น 0 เพื่อบันทึก query ทั้งหมด แล้วตรวจสอบว่ามี query ที่มีรูปแบบเดียวกันรันต่อเนื่องกันหรือไม่ สำหรับ Rails มี bullet gem และสำหรับ Django มี django-debug-toolbar เป็นเครื่องมือตรวจจับ
เพียงแค่ตระหนักในขั้นตอน code review ว่า "มี await อยู่ภายใน loop หรือไม่" ก็สามารถป้องกัน N+1 ได้เป็นจำนวนมากก่อนที่จะเกิดปัญหา



Agentic RAG คือสถาปัตยกรรมที่ LLM ทำหน้าที่เป็น Agent โดยวนซ้ำกระบวนการสร้าง Query ค้นหา ประเมินผลลัพธ์ และตัดสินใจค้นหาซ้ำอย่างอิสระ เพื่อให้ได้ความแม่นยำของคำตอบที่เหนือกว่า RAG แบบถาม-ตอบทั่วไป

RRF (Reciprocal Rank Fusion) คือวิธีการให้คะแนนเพื่อรวมผลลัพธ์การจัดอันดับจากหลายวิธีการค้นหาเข้าด้วยกัน โดยการนำค่าส่วนกลับของอันดับจากแต่ละวิธีมารวมกัน ทำให้สามารถผสานระบบคะแนนที่แตกต่างกันได้โดยไม่ต้องทำการ Normalization

วิธีการออกแบบที่แยกระบบ AI และโครงสร้างพื้นฐานการประมวลผลข้อมูลออกจากกันทั้งในเชิงกายภาพและเชิงตรรกะ เพื่อขจัดความเสี่ยงการรั่วไหลของข้อมูลส่วนบุคคลในเชิงโครงสร้าง โดยมีตัวอย่างที่เป็นแบบฉบับ ได้แก่ การแยก Tenant และการดำเนินงานแบบ On-premises

n8n (nodemation) คือแพลตฟอร์มอัตโนมัติแบบโอเพนซอร์สที่ช่วยสร้างเวิร์กโฟลว์อัตโนมัติด้วยวิธี no-code/low-code

สถาปัตยกรรม RAG รุ่นถัดไปที่ผสมผสาน Knowledge Graph และการค้นหาแบบ Vector เข้าด้วยกัน โดยใช้ประโยชน์จากความสัมพันธ์ระหว่าง Entity เพื่อเพิ่มความแม่นยำในการค้นหา