Нужно мнение с учетом отношений - PullRequest
0 голосов
/ 20 января 2020

Очень долго я искал решение для этой проблемы:

Допустим, у нас есть 2 таблицы: одна таблица - таблица клиентов, а вторая - таблица ClientAssignment: таблица ClientAssignment связана с таблицей Clients:

public function assignment()
{
    return $this->hasOne(ClientAssignment::class, 'client_id');
}

теперь, когда я хочу посчитать, сколько ClientAssignment имеет клиентов, и я делаю это так:

$users =[1,2,3,4 .....]
$userAssignments = array();

foreach ($users as $user) {

    $user_assignments = Client::whereHas('assignment', function ($query) use ($user) {
     $query->where('assigned_id', $user);
    });

     $ua['user_id'] = $user;
     $ua['count'] = $user_assignments->count();
     array_push($userAssignments, $ua);
   }

Код работает хорошо, но он достигает производительности и времени выполнения запроса ~ 20 + секунд на сравнительно небольшой таблице с клиентами из 80 тыс., мой вопрос, может ли быть другой способ сделать то же самое, но с минимальной производительностью и временем выполнения запроса?

Ответы [ 2 ]

1 голос
/ 20 января 2020

В соответствии с вашим постом, я думаю

Client --- hasOne ----> ClientAssignment  <----- hasMany ---- User
                    [client_id, assigned_id]

Так что User может иметь много Client до ClientAssignment,

Однако, ваши client_id и assigned_id все в client_assignment таблице. Таким образом, вы не можете использовать hasManyThrough, это так же, как сводную таблицу;

К счастью, вы можете напрямую сосчитать client_id и получить assigned_id как user_id, просто используйте эту сводную таблицу.

Запрос выглядит следующим образом (используйте distinct(client_id) для предотвращения грязных записей):

ClientAssignment::whereIn('assigned_id', $users)
                  ->groupBy('assigned_id')
                  ->select('assigned_id AS user_id',
                            DB::raw('COUNT(DISTINCT(client_id)) AS count'))
                  ->get()->toArray();

И добавьте индекс assigned_id для повышения производительности.

$table->index('assigned_id');
0 голосов
/ 20 января 2020

Используйте count()


Client::first()->assignments->count();

// Or

Client::find(ID)->assignments()->count();

// or ...


...