Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

zoldic's avatar

Query vs ForEach Loop, Which one has the better performance?

Hi folks, I'm wondering between Query vs Foreach loop, Which one has the better performance?

Here is a simple example, my web app, has a reply table and like table, the reply and like has onetomany relationship, a reply can have many likes and a like belong to a reply

and in this function I need to get a like record/model that is liked by current auth user

1, Using query

public function likeReply(Request $request)
{
    $reply = Reply::find($request->id);

    $likeByUser = Like::where([
            ['user_id', '=', Auth::id()],
            ['likeable_type', '=', 'App\Reply'],
            ['likeable_id', '=', $reply->id],
        ])->first();  //The Query

    //other line of code
}

2, Using foreach loop

public function likeReply(Request $request)
{
    $reply = Reply::find($request->id);
    
    $likeByUser = null;
    foreach($reply->likes as $like)
    {
            if($like->user_id == Auth::id() &&
            $like->likeable_type == 'App\Reply' &&
            $like->likeable_id == $replyId)
            {
                $likeByUser = $like;
                break;
            }
        }  //The Foreach loop

    //other line of code
}

Both method can get the like record/model that is liked by current auth user (it has the same result)

But I'm wondering which one has a better perfomance (speed, etc), if for eg. in my like table has 10,000 likes record in the DB? and if you know which one perform better, can you give me a simple explanation why it has better perfomance?

Thanks

0 likes
9 replies
crnkovic's avatar

Always narrow down queries down to specific conditions you need. Don't fetch all the records and then loop through to find what you need.

In first scenario, database system will go into record #1 - check if it matches and if it doesn't, just go to the next record (potentially could be a few records caught). In second scenario, database will get all records (potentially millions) and then loop through with PHP to check if it matches.

Second scenario is a lot slower.

1 like
zoldic's avatar

Hi thanks crnkovic for replying

1, What do you mean by "Always narrow down queries down to specific conditions you need". Can you give me an example about it using my previous scenario?

2, BTW, the reply and like has onetomany relationship, a reply can have many likes and a like belong to a reply.

so for eg. I have 5,000 replies in my DB, and 10,000 likes in my DB

and for eg. in reply id 2000, the reply has 10 likes, and using my previos function code scenario 1or2, if the current auth user has like the reply id 2000 it will return $likeByUser record and if there is none it will return null

Shouldn't it be the scenario1 will search all the records while scenario2 will only loop through 10likes from reply id 2000? so scenario2 should be faster?

Thanks

Cronix's avatar

Why don't you set up a relationship between likes and replies, so you can just have a single query that gets the reply along with its likes instead of getting them separately?

zoldic's avatar

Yes, they have relationship already, the reply and like has onetomany relationship, a reply can have many likes and a like belong to a reply

Cronix's avatar

Then why are you first getting the $reply in one query and then getting the Like where the likable_id is = to $reply->id?

zoldic's avatar

My bad, I make a little mistake with my code, I have fixed it

It is not

$reply = Reply::find($replyId);

the correct one is this

$reply = Reply::find($request->id);
cloudhorizon's avatar
Level 12

It seems you have more than 1 thing that can be liked? In that case simply use polymorphic relations

When polymorphic relation is set up correctly, all you should do to get the likes is:

$reply = Reply::with('likes')->find($request->id);
dd($reply->likes);

This will automatically get only likes of likeable_type App\Reply. And to get only likes of current user:

$reply = Reply::with(['likes' => function($query) {
    $query->where('user_id', Auth::id());
}])->find($request->id);

dd($reply->likes);

Haven't tested but it should work.

1 like
kobear's avatar

IMHO, I always try to make the database do as much of the work for me as possible. It is designed for this purpose, so if you design your schema properly, including indexing, whatever work you can do at the database layer will always speed up your application.

So, with that in mind, #1 is the more efficient, faster method.

1 like
zoldic's avatar

Thanks for cloudhorizon & kobear for the reply & advice

Please or to participate in this conversation.