دليلك الاحترافي للـ Subqueries المعقدة في Laravel Eloquent
أكيد مريت بالموقف ده: عندك جدول للطلبات (Orders) وعايز تجيب مع كل طلب اسم العميل وآخر تاريخ طلب ليه أو مجموع مبيعاته، وتلاقي نفسك بتعمل Loop في الـ Controller وبترمي كويري جوه كويري (N+1 Problem)، والنتيجة إن الموقع بيبقى بطيء جداً وقاعدة البيانات بتبدأ تشتكي. النهاردة هنتكلم عن الحل السحري اللي بيخليك تعمل كل ده في طلب واحد (Single Query) باستخدام الـ Subqueries المعقدة في Laravel Eloquent.
Table of contents [Show]
ليه محتاجين نستخدم الـ Subqueries؟
الاستعلامات الفرعية أو Subqueries هي طوق النجاة لما تحتاج تطلع إحصائيات (Aggregates) مرتبطة بسجلات معينة. بدلاً من تحميل البيانات كلها في الذاكرة (Memory) وبعدين تعمل ليها معالجة باستخدام PHP، إحنا بنخلي الـ Database Engine هو اللي يعمل الشغل الصعب ده، وده بيوفر كتير في استهلاك الموارد وبيدي أداء احترافي.
استخدام selectSub لإضافة أعمدة محسوبة
لو عايز تجيب بيانات جدول أساسي ومعاها عمود إضافي بيحسب حاجة معينة، selectSub هو صديقك الصدوق. تخيل عندك جدول Users وعايز تجيب مع كل يوزر تاريخ آخر عملية شراء ليه بدون ما تعمل Join تقيل.
$latestOrder = Order::select('created_at')
->whereColumn('user_id', 'users.id')
->latest()
->limit(1);
$users = User::addSelect(['last_order_at' => $latestOrder])->get();
هنا الـ Eloquent بيحول الكود ده لـ SQL Query ذكية جداً بتجيب التاريخ في نفس سطر الاستعلام، وده بيقلل الضغط على قاعدة البيانات بشكل رهيب.
الاحترافية مع joinSub
أحياناً الـ selectSub مش كفاية، خصوصاً لما تحتاج تستخدم نتائج الاستعلام الفرعي ده كأنها جدول حقيقي تعمل عليه Join. هنا بيجي دور joinSub. دي الميزة اللي بتخليك تتعامل مع استعلامات معقدة جداً كأنها جداول جاهزة.
تخيل عايز تجيب قائمة بالمستخدمين ومعاهم إجمالي مبالغ الطلبات بتاعتهم، بشرط تكون المبالغ دي محسوبة مسبقاً في استعلام فرعي:
$salesQuery = Order::select('user_id')
->selectRaw('SUM(price) as total_spent')
->groupBy('user_id');
$users = User::joinSub($salesQuery, 'order_totals', function ($join) {
$join->on('users.id', '=', 'order_totals.user_id');
})->get();
الطريقة دي بتخليك تتحكم في الـ Complex Joins بشكل نظيف ومنظم جداً جوه الـ Codebase بتاعك، وبتحافظ على نظافة الـ Eloquent Model.
نصيحة أخيرة للمبرمجين
نصيحتي ليك يا بطل: المهارة مش في كتابة كود طويل، المهارة في كتابة كود Performant. دايماً استخدم الـ EXPLAIN في الـ SQL عشان تشوف الكويري بتاعك شغال إزاي. الـ Laravel Eloquent أدواته قوية جداً، بس لازم تكون فاهم إيه اللي بيحصل "تحت الغطاء" (Under the hood) عشان تتجنب مشاكل الأداء قبل ما تظهر في الإنتاج.
ابدأ جرب الـ Subqueries في مشاريعك الصغيرة، ولما تتعود عليها، هتلاقي نفسك بتكتب استعلامات كانت بتبان مستحيلة في دقايق معدودة. بالتوفيق في رحلتك البرمجية!