with() names the relationships to load with the query, one WHERE ... IN query each. Add :id,name to select only those columns, always including the key Eloquent matches on:
use App\Models\Order;
measure('with()', function () {
foreach (Order::with(['customer:id,name', 'products:id,title'])->get() as $order) {
$line = "{$order->customer->name} bought {$order->products->count()} titles";
}
});Output
with() 3 queries 22.1 ms in MySQL 264.4 ms in all
From 4,001 queries to 3, and from nearly 4 seconds to a quarter of one. Each customer is fetched once and shared by all its orders. The rest is PHP building 7,492 models, so paginate (Ordering and Pagination) before you eager load. A protected $with = ['customer']; property eager loads on every query, and without('customer') drops it for one; every query pays for it, so use it sparingly.