DEV Community

Cover image for Indexing and Query Optimization in Laravel
SURULIRAAJAN
SURULIRAAJAN

Posted on

Indexing and Query Optimization in Laravel

When your Laravel app starts dealing with a lot of data, performance becomes a real challenge. You might notice that some pages take too long to load, or certain queries are eating up resources. The good news is, with the right approach, you can fix most of these issues. Two of the most powerful techniques are indexing and query optimization.

What is Indexing and Why Does It Matter?

Imagine searching for a word in a book without an index – you’d have to flip through every page until you find it. That’s exactly what happens when your database doesn’t have an index: it scans the entire table, row by row.

Now, if you add an index on the right column, the database can jump directly to the exact location, just like using a book’s index. That’s why indexing is a game-changer for queries that run often.

Adding Indexes in Laravel
Laravel makes this super easy with migrations. Here are a few examples:

Unique index (great for emails or usernames):
$table->unique('email');
Regular index (good for foreign keys like user_id):
$table->index('user_id');
Composite index (for multiple columns used together):
$table->index(['category_id', 'price']);

Not every column needs an index though. Use them wisely—columns with just a few values (like “active” or “inactive”) usually don’t benefit from indexing.

Query Optimization in Laravel

Indexing is just half the story. The way you write your queries also makes a huge difference. Here are some practical tips:

Select only what you need

Instead of grabbing every column, just fetch the fields you’ll use.

User::select('id', 'name', 'email')->get();
Enter fullscreen mode Exit fullscreen mode

Process large datasets in chunks

If you’re working with thousands of records, don’t load them all at once.

User::chunk(100, function ($users) {
    foreach ($users as $user) {
        // process
    }
});
Enter fullscreen mode Exit fullscreen mode

Avoid the N+1 problem with eager loading

If you’re loading related models, use with() to reduce the number of queries.

$posts = Post::with('user')->get();
Enter fullscreen mode Exit fullscreen mode

Use Query Builder for complex queries

Sometimes raw SQL or Query Builder is faster than Eloquent.

$orders = DB::table('orders')
    ->join('users', 'orders.user_id', '=', 'users.id')
    ->select('users.name', DB::raw('SUM(orders.total) as total_spent'))
    ->groupBy('users.name')
    ->get();
Enter fullscreen mode Exit fullscreen mode

Check what’s really happening with EXPLAIN

When in doubt, use EXPLAIN to see how MySQL executes your query. This tells you if it’s using an index or doing a full scan.

Don’t Forget Caching

If you have queries that don’t change often (like a product list), caching can save you a lot of resources.

$users = Cache::remember('users_list', 3600, function () {
    return User::select('id', 'name')->get();
});
Enter fullscreen mode Exit fullscreen mode

Conclusion

Laravel makes it easy to write queries, but as your app grows, performance tuning becomes just as important as writing clean code. Indexing the right columns, optimizing your queries, and caching results when possible can make your app run lightning fast, even with millions of records.

So next time your app feels sluggish, don’t just blame the server—take a closer look at your database queries. A well-placed index or a small query tweak might be all you need.

Top comments (0)