Prevent model hydration on Eloquent queries

First of all, this is a really good question. All those haters out there, give the OP a break! He's pro-Laravel and this isnt an Eloquent sucks question, so cool it.

In my opinion,

Hydrating models rarely affects application performance

There are so many ORMs out there and if you look at any framework, these questions keep popping up - but the truth, as I've come to realize, is that ORMs hardly affect performance.

More often than not the culprits are the queries themselves and not the ORM

Let me give you a few examples of why Eloquent models may perhaps be slower than DB facade queries:

1. Model events:

When you have model events (such as saving, creating, etc.) in your models, they sometimes slow down processing. Not to say that events should be avoided, you just need to be careful when and when not to use them

2. Loading Relationships:

Countless times have I seen folks load relationships using appends lists provided by Eloquent and sometimes models have 5-10 relationships. That's 5-10 joins each time you fire an Eloquent query! If you compare that with a DB facade query, it would definitely be faster. But then again, who's the real culprit? Not the ORM, it's the queries (with the extra joins!)

As an example, not so long someone asked a question on this and he/she wondered why an Eloquent query was slower than a raw one. Check it out!

3. Not understanding what triggers an Eloquent query

This is by far the most prominent reason why people think ORMs are slower. They usually (not always) don't understand what triggers a query.

As an example, lets say you want to update a products table and set the price of product #25 to $250.

Perhaps, you write in your controller, the following:

$id = 25;
$product = Product::findOrFail($id);
$product->price = 250;
$product->save();

Then, your colleague says hey, this is super slow. Try using DB facade. So you write:

$id = 25;
DB::table('products')->where('product_id', $id)->update(['price' => 250]);

And boom! It's faster. Again, the culprit isn't the ORM. It's the query. The one above is actually 2 queries, the findOrFail triggers a select * query and the save triggers an update query.

You can and should write this as a single query using Eloquent ORM like so:

Product::where('product_id', 25)->update(['price' => 250]);

Some Good Practices for Query Optimization

  1. Have your database do most of the work instead of PHP: E.g. instead of iterating over Eloquent collections, perhaps frame your DB query in such a manner that the database does the work for you.

  2. Mass Updates Over Single Updates: Pretty obvious. Avoid saving models in for loops, yuk!

  3. For heavy queries, use transactions: DB transactions avoid re-indexing on every insert. If you really need to call say thousands of inserts/update queries in a single function call, wrap them into a transaction

  4. Last but not the least, when in doubt check your query: If you're ever ever ever in doubt, that perhaps the ORM is the real culprit - think again! Check your query, try and optimize it.

If the ORM is slowing things down, use obervers or the Laravel debugbar to compare the queries with and without the ORM. More often than not, you'll find that the queries are different, and the difference isnt in hydration but the actual queries themselves!


Yes, is possible using the 'getQuery' or 'toBase' method. For example:

User::where('age', '>', 34)->getQuery()->get();

or

User::where('age', '>', 34)->toBase()->get();