← Back to blog

Eloquent Performance: Avoid SELECT *

| Laravel

This article was published over 2 years ago. Some information may be outdated.

Consider the following code:

# Controllers/UsersController

public function index()
{
    return view('posts.index', ['posts' => Post::paginate()]);
}
# views/posts/index.blade.php

@foreach ($posts as $post)
    <h2>{{ $post->title }}</h2>
@endforeach

By default, Laravel selects all the columns when using Eloquent:

-- Took 32 ms to execute
select * from `posts` limit 0, 15;

In this query, you are selecting the entire column set, but you only use one of them: the title.

If you look at the database diagram, you will see that the content column is of type longtext which means it can hold up to 4GB of data.

That query took 32 ms on my machine. Now watch what happens when you select only the title column:

-- Took 2 ms to execute
select title from posts;

A big difference, 32 ms vs 2 ms.

The rule is simple: only select the columns that you need:

Post::query()
    ->select('title')
    ->paginate();

You can also use the with method to select specific columns from relationships:

Post::query()
    ->select('title')
    ->with('user:id,name')
    ->paginate();

In the upcoming post, I will discuss eager-loading.

Summary

  • Stop using SELECT * -- selecting all columns wastes time and memory, especially when tables contain large text or blob columns.
  • Select only what you need -- use ->select('column1', 'column2') to fetch just the columns your view or API actually uses.
  • Scope relationship selects too -- use with('relation:id,column') to avoid loading unnecessary data from eager-loaded relationships.
Share