- بواسطة x32x01 ||
مشكلة N+1 في SQL: لما تجيب كل حاجة لوحدها 📝
البوست اللي فات اتكلمنا عن الصينية المليانة أكل وانت طلبت ساندوتش واحد 🍔
هنتخيل إن ربنا كرمك واشتريت الكافيه وبقيت المدير 😎
High Performance MySQL
البوست اللي فات اتكلمنا عن الصينية المليانة أكل وانت طلبت ساندوتش واحد 🍔
هنتخيل إن ربنا كرمك واشتريت الكافيه وبقيت المدير 😎
- دخلت تعمل جرد للطلبات اليومية
- طلبت من الويتر قايمة الطلبات وكل طلب فيه إيه
- الويتر رجع جابلك كل الطلبات لوحدها
- بعدين مشي وجابلك الأصناف لوحدها
نفس القصة بتحصل جوه الـ Database 💻
لو كتبنا الكويري بالشكل ده: SQL:
-- نجيب الطلبات
SELECT * FROM orders;
-- بعدين لكل طلب نجيب الأصناف
SELECT * FROM items WHERE order_id = 1;
SELECT * FROM items WHERE order_id = 2;
SELECT * FROM items WHERE order_id = 3; - لو عندك 100 طلب → هتعمل 101 Query 😱
- كأنك بتبص في ورقتين وتحاول تفهم كل صنف تابع لأي طلب
ليه دي تعتبر من مشاكل N+1 ⚠️
- بتتعامل مع الداتا بطريقة ساذجة:
- تجيب الطلبات لوحدها
- بعدين ترجع تجيب الأصناف لوحدها
- تدخل نفسك في Queries زيادة من غير لازمة
- النتيجة: بطء في الأداء، استهلاك أكبر للـ Server، وزيادة التحميل على الشبكة
الحل: استخدم INNER JOIN 🛠️
بدل ما تجيب كل حاجة لوحدها، نقدر نستخدم INNER JOIN ونربط الطلبات بالأصناف في نفس الاستعلام: SQL:
SELECT o.id AS order_id,
o.total,
i.name AS item_name
FROM orders o
INNER JOIN items i
ON o.id = i.order_id; - كده جبت كل الطلبات مع الأصناف بتاعتها في ورقة واحدة ✅
- مثال النتيجة:
- طلب رقم 1 = برجر 🍔
- طلب رقم 2 = قهوة ☕
- طلب رقم 3 = بيتزا 🍕
فايدة INNER JOIN 🎯
- بيجيبلك بس الطلبات اللي ليها أصناف مرتبطة بيها
- بتقلل عدد الـ queries وتخلي الأداء أسرع
- مناسب جدًا لأي database كبيرة أو application فيه علاقات بين الجداول
المرة الجاية: لو فيه طلبات ملهاش أصناف؟ 🤔
- هل نعرضها؟ ولا نرميها؟
- هنا هنحتاج نوع تاني من الـ JOIN زي LEFT JOIN
- ده هيسمحلك تشوف كل الطلبات حتى لو ملهاش أصناف مرتبطة
مصادر للتعلم العميق 📚
لو حابب تتعلم أكتر عن تحسين أداء الـ Database ومشاكل زي دي، شوف كتاب:High Performance MySQL
- تأليف: Baron Schwartz, Peter Zaitsev, Vadim Tkachenko
التعديل الأخير: