x32x01
أدارة أكتب كود
- بواسطة x32x01 ||
من أسوأ الأشياء التي قد تستخدمها داخل تطبيق لارافيل هي دالة whereHas بشكل متداخل , لأنها تضرب الأداء بشكل سيئ جداً (عن تجربة) .
استخدام دالة whereHas مفيد ومافيه أي مشكلة , ولكن إستخدام whereHas بشكل متداخل يسبب مشاكل في الأداء خاصة إذا كانت البيانات كبيرة .
نأخذ مثال :-
المثال التالي سيئ (حيث تم استخدامها بشكل متداخل)
لماذا هذا الاستعلام سيئ ويسبب مشاكل في الأداء ؟
الجواب :-
- تكرار الاستعلامات الفرعية: يتم تنفيذ استعلام فرعي لكل سجل يتم معالجته، مما يؤدي إلى آلاف الاستعلامات الإضافية إذا كانت البيانات ضخمة.
- يقوم بمسح كامل للجدول Full Table Scan لجدول prices يعني قراءة كل صف في الجدول حتى يتم العثور على السجلات المطابقة، مما يؤدي إلى أداء سيئ مع الجداول الكبيرة.
كيف نعالجها .؟
استخدام العلاقات المترابطة بدلاً من التداخل
استخدام with لتحميل العلاقات مسبقًا
استخدام دالة whereHas مفيد ومافيه أي مشكلة , ولكن إستخدام whereHas بشكل متداخل يسبب مشاكل في الأداء خاصة إذا كانت البيانات كبيرة .
نأخذ مثال :-
المثال التالي سيئ (حيث تم استخدامها بشكل متداخل)
PHP:
Subscription::whereHas('features', function ($query) {
$query->whereHas('prices', function ($query) {
$query->where('amount', '>', 100);
});
})->get();
لماذا هذا الاستعلام سيئ ويسبب مشاكل في الأداء ؟
الجواب :-
- تكرار الاستعلامات الفرعية: يتم تنفيذ استعلام فرعي لكل سجل يتم معالجته، مما يؤدي إلى آلاف الاستعلامات الإضافية إذا كانت البيانات ضخمة.
- يقوم بمسح كامل للجدول Full Table Scan لجدول prices يعني قراءة كل صف في الجدول حتى يتم العثور على السجلات المطابقة، مما يؤدي إلى أداء سيئ مع الجداول الكبيرة.
كيف نعالجها .؟
استخدام العلاقات المترابطة بدلاً من التداخل
PHP:
- Subscription::whereHas('features.prices', function ($query) {
$query->where('amount', '>', 100);
})->get();
استخدام with لتحميل العلاقات مسبقًا
PHP:
Subscription::with(['features.prices' => function ($query) {
$query->where('amount', '>', 100);
}])->get();