مقاله

DB::table vs Model::query — performance، خوانایی و سناریوهای report، bulk update و join پیچیده در Laravel.

Query Builder در مقابل Eloquent — کی کدام را استفاده کنیم؟

Query Builder در مقابل Eloquent — کی کدام را استفاده کنیم؟

«Eloquent کند است» جمله‌ای است که نیمه‌درست می‌شنوم. Eloquent روی Query Builder ساخته شده — کندی از N+1، select * و hydration بی‌جهت است نه از ORM ذاتاً. با این حال گزارش ۵۰۰هزار ردیفی یا bulk update گاهی DB::table منطقی‌تر است.

Eloquent چه اضافه می‌کند؟

  • Model instance با cast و accessor
  • Relation، event، observer
  • Scope و policy integration

Query Builder چه می‌دهد؟

  • سبک‌تر — stdClass یا array
  • کنترل مستقیم join و select
  • بدون event model

مثال یکسان — لیست ساده

// Eloquent
Post::published()->with('category')->paginate(15);

// Query Builder
DB::table('posts')
    ->join('categories', 'categories.id', '=', 'posts.category_id')
    ->where('posts.status', 'published')
    ->select('posts.*', 'categories.name as category_name')
    ->paginate(15);

برای CRUD اپلیکیشن Eloquent خواناتر است.

گزارش aggregate

DB::table('orders')
    ->selectRaw('DATE(created_at) as day, SUM(total) as revenue')
    ->where('created_at', '>=', now()->subDays(30))
    ->groupBy('day')
    ->orderBy('day')
    ->get();

نیازی به model hydration نیست.

Bulk update

DB::table('posts')
    ->where('status', 'draft')
    ->where('created_at', '<', now()->subYear())
    ->update(['status' => 'archived']);

Eloquent Model::query()->update() هم می‌دهد اما event نمی‌دهد — بدانید چه می‌خواهید.

chunk و cursor — حافظه

Post::query()->cursor()->each(function (Post $post) {
    // پردازش یکی یکی
});

DB::table('logs')->orderBy('id')->chunk(500, function ($rows) {
    // ...
});

برای export بزرگ ضروری — بهینه‌سازی.

ترکیب: Eloquent از DB

$ids = DB::table('post_tag')
    ->where('tag_id', $tagId)
    ->pluck('post_id');

Post::whereIn('id', $ids)->with('user')->get();

کی Eloquent؟

CRUD، relation، business app، تست با factory.

کی Query Builder؟

Dashboard آماری، ETL سبک، migration data، admin export سنگین.

Raw SQL

DB::select('SELECT ... WHERE user_id = ?', [$id]);

آخرین راه — binding همیشه.

جمع‌بندی

پیش‌فرض Eloquent؛ استثنا Query Builder برای performance مشخص. روابط فقط در Eloquent. Transaction برای هر دو یکسان.

بهینه‌سازی query