Database Query Optimization

2025-11-23 وقت القراءه : 2 دقائق

قاعدة البيانات غالباً أبطأ نقطة في تطبيقك. استعلام سيء واحد يمكن أن يبطئ API بالكامل ويسبب انهيار تحت الضغط.


أهم 7 تقنيات لتحسين الاستعلامات

1. حل مشكلة N+1 Query ⚡

php
// ❌ سيء - 101 استعلام لـ 100 منتج
$products = Product::all();
foreach ($products as $product) {
    echo $product->category->name;
}


// ✅ ممتاز - استعلامين فقط
$products = Product::with('category')->get();

2. اختر الأعمدة المطلوبة فقط

php
// ❌ سيء
$users = User::all();


// ✅ ممتاز
$users = User::select(['id', 'name', 'email'])->get();


// مع العلاقات
$posts = Post::select(['id', 'title'])
    ->with(['author:id,name'])
    ->get();


3. استخدم Chunk للبيانات الكبيرة

php
// ❌ سيء - Memory Exhausted
$users = User::all();


// ✅ ممتاز
User::chunk(1000, function ($users) {
    foreach ($users as $user) {
        $user->process();
    }
});


4. Query Scopes لإعادة الاستخدام

php
// في Model
public function scopeActive($query) {
    return $query->where('status', 'active');
}


// الاستخدام
$products = Product::active()->inStock()->get();


5. أضف Database Indexes

php
// في Migration
Schema::table('products', function (Blueprint $table) {
    $table->index('category_id');
    $table->index(['status', 'stock']); // Composite
});

متى تستخدم Index:

  • أعمدة في WHERE, JOIN, ORDER BY
  • Foreign keys


6. استخدم Pagination

php// ❌ سيء
$products = Product::all();


// ✅ ممتاز
$products = Product::cursorPaginate(20);


7. Batch Operations

php
// ❌ سيء - 1000 query
foreach ($users as $user) {
    User::where('id', $user->id)->update(['status' => 'active']);
}


// ✅ ممتاز - query واحد
User::whereIn('id', $userIds)->update(['status' => 'active']);

Quick Wins للأداء الفوري

php
// 1. Eager Loading دائماً
Order::with(['user', 'items'])->get();


// 2. استخدم exists() للتحقق
if (User::where('email', $email)->exists()) { }


// 3. increment/decrement مباشرة
Product::where('id', $id)->increment('views');


// 4. Cache الاستعلامات المتكررة
Cache::remember('popular', 3600, fn() => 
    Product::where('views', '>', 1000)->get()
);

Slow Query Detection

php// في AppServiceProvider
DB::listen(function ($query) {
    if ($query->time > 1000) {
        Log::warning('Slow query', [
            'sql' => $query->sql,
            'time' => $query->time
        ]);
    }
});


Performance Checklist

عند كتابة Query جديد:

✅ استخدمت select() للأعمدة المطلوبة؟

✅ استخدمت Eager Loading؟

✅ الأعمدة في WHERE عليها indexes؟

✅ استخدمت Pagination للبيانات الكبيرة؟

✅ يمكن cache النتيجة؟


الفوائد

✅ 90% أقل queries على Database

✅ 10x أسرع في الاستجابة

✅ 70% تقليل في استهلاك الموارد

إضافة تعليق
Loading...