في هذه الصفحة
المقدمة
الـ N+1 Problem هي مشكلة في طريقة تعاملنا مع قواعد البيانات ، ومن المشاكل اللي لازم احنا كمطورين ناخد بالنا منها لانها ليها ضريبة كبيرة أوي خصوصا في التعامل مع البيانات الكبيرة.
فورقة وقلم وتعالوا نتعرف على المشكلة دي وازاي نقدر نتجنبها
N+1 Problem
الـ N+1 Problem هي مشكلة بتخلينا نعمل عدد Requests أكبر بكتير من اللي محتاجينه وعشان نكون محددين فبالتحديد N+1 Requests على الرغم اننا ممكن نحل نفس المشكلة بعدد Requests أقل.
وطبعًا الـ Requests الكثيرة اللي ملهاش لزمة بتشغل الـ Database وبالتالي الموقع أو التطبيق بتاعنا بيكون أبطأ و بيدينا Performance سيء.
وعشان نفهم كويس خلينا ناخد مثال, أنت بتبرمج موقع لمكتبة وعاوز بيانات الكتب الأكثر مبيعًا وكمان بيانات عن المؤلفين للكتب دي عشان تعرضها في صفحة مخصصة.
بيانات الكتب الأكثر مبيعًا في Books Table
وبيانات المؤلفين في Authors Table
فأول حل هيجي في بالنا:
- نكتب Query نجيب بيه List of Books من Books Table
Select * from books;
- لكل كتاب في قائمة الكتب هنعمل Request علي ال
Authors Table
عشان نجيب معلومات مؤلف الكتاب.
Select * from authors where authorID = <>;
هنا إحنا روحنا للـ Database مرة عشان قائمة الكتب و عدد N من المرات - بعدد الكتب - عشان نجيب معلومات مؤلف كل كتاب.
دا هيخلي تحميل الصفحة بتاعت الكتب الأكثر مبيعًا على موقعك بطيئة جدًا بينما ممكن نحسّن من ال Performance بتاعنا بإننا نطلب البيانات من قاعدة البيانات في عدد أقل من ال Requests ودا بإننا نعمل اعادة هيكلة للـ Queries بتاعتنا.
SELECT Books.*, Authors.* FROM Books JOIN Authors ON Books.author_id = Authors.id;
هنا إحنا حلينا المشكلة أننا استخدمنا Join وقد يبدو ال Query هنا أكبر ولكنه أكفأ لأنه قاعدة البيانات بتعمل Query Optimisation فتقدر تسرع الـ Query اللي قد يبدوا انه كبير بينما العدد الكبير من الـ Queries المنفصلة بيشغل قاعدة البيانات ومفيهوش مجال للـ Optimization
الـ N+1 من المشكلات الشائعة لأن كل البيانات اللي بنتعامل معاها في التطبيقات والمواقع بتكون مرتبطة ببعض بشكل ما أو بآخر , فلو عندنا موقع تواصل وحبينا نجيب ال Posts و نجيب ال Comments علي كل Post أو عندنا موقع توصيل طلبات وحبينا نعرض المطاعم وكذلك الأكلات اللي بيقدمها كل مطعم إلخ…
الحلول الممكنة:
- ال Joins زي ما شرحنا في المثال
- بما إن استخدام الـ ORMs من الحاجات اللي بتعرضنا بسهولة لظهور هذه المشكلة, نقدر نستعمل ال Eager Loading لحل المشكلة دي وهنا الـ ORM بيقوم بطلب البيانات المرتبطة ببعض من قبل استخدامها.
وكنا اتكلمنا قبل كده في ورقة عن الـ ORM تقدروا تشوفوها من هنا