0

please tell me how can I improve the database query in Laravel?

there are two methods in the repository

    public function getCountAdverts(): array
    {
        return [
            Advert::STATUS_PUBLISHED => $this->getCount(Advert::STATUS_PUBLISHED),
            Advert::STATUS_CLOSED => $this->getCount(Advert::STATUS_CLOSED),
            Advert::STATUS_NOT_PUBLISHED => $this->getCount(Advert::STATUS_NOT_PUBLISHED),
            Advert::STATUS_MODERATION => $this->getCount(Advert::STATUS_MODERATION),
        ];
    }

    private function getCount(string $status): int
    {
        return Advert::where('status', $status)->count();
    }

How can I get the same array without just 4 queries?

enter image description here

enter image description here

1
  • Do everything in one quesy since there are no other changes Commented May 7, 2020 at 19:29

2 Answers 2

3

You can use that Eloquent returns Collection. So work with collection.

public function getCountAdverts(): array
{
    $adverts = Advert::get(); //this will be collection of all Adverts(Illuminate\Support\Collection)

    return [
        Advert::STATUS_PUBLISHED => $this->getCount($adverts, Advert::STATUS_PUBLISHED),
        Advert::STATUS_CLOSED => $this->getCount($adverts, Advert::STATUS_CLOSED),
        Advert::STATUS_NOT_PUBLISHED => $this->getCount($adverts, Advert::STATUS_NOT_PUBLISHED),
        Advert::STATUS_MODERATION => $this->getCount($adverts, Advert::STATUS_MODERATION),
    ];
}

private function getCount($adverts, string $status): int
{
    return $adverts->where('status', $status)->count();
}
Sign up to request clarification or add additional context in comments.

5 Comments

How is this different than what he already has, still 4 queries will be executed???
There wil be only 1 query - $adverts = Advert::get(); And then you will work with Collection (saved in memory). Try It, you will see it. Collections are great in Laravel.
This is an interesting approach, I did not know. I learned something new today. Kudos to you!!!
@Autista_z tell me if there will be a lot of ads in the database, then how Advert::get() will work? Will there be a lot of time spent on the request?
@Vlad it can be problem if there will be a lot of items in database (10k+), because all will save in the ram. With a lot of records its not the best solution.
1

Instead of executing multiple queries, you can do everything in one Query

Advert::whereIn('status'[
    Advert::STATUS_PUBLISHED,
    Advert::STATUS_CLOSED,
    Advert::STATUS_NOT_PUBLISHED,
    Advert::STATUS_MODERATION
])
->groupBy('status')
->select(DB::raw('count(*)'), 'status')
->get()
->toArray();

You can remove whereIn condition and you will get the count for all the type of statuses.

Some Suggestions:

  1. You can index status column
  2. If statuses are prefixed then you can use Enum in the database only if they are not changng in the future.

Hope this helps!!!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.