В настоящее время я работаю с таблицей, содержащей миллионы строк. Мне нужно эффективно обработать около миллиона таких строк, чтобы получить конкретные данные, например общее количество или количество, сгруппированное по определенным критериям. В настоящее время для достижения этой цели я использую метод Laravel chunk()
. Однако время ответа конечной точки в настоящее время довольно медленное и занимает много времени.
$incidents = Incident::where('canceled_by', null)
->with(['detail.classification'])
->whereIn('period_id', $requestAll['typeValue'])
->where($views[$requestAll['view']]['where'], $views[$requestAll['view']]['whereValue']);
$incidents->chunk(100000, function ($chunkIncidents) use (&$generalInformation, $views, $requestAll) {
// Manipulate data
});
Использование способа Eloquent с большим количеством элементов может быть медленным, поскольку каждая строка сопоставляется со своей моделью. Вы также делаете это для двух дополнительных моделей. Было бы быстрее просто получить необходимые столбцы, используя фасад БД.
DB::table('incidents')
->select('incidents.id', 'details.description')
->whereNull('canceled_by')
->leftJoin('details', 'incidents.id', '=', 'details.incident_id')
Это также может быть медленным, поскольку Builder в Laravel использует коллекции для получения результатов. Сборы также выполняются медленно при использовании большого количества данных. Прямое заявление было бы самым быстрым способом. Вы можете сгенерировать sql, используя Eloquent, и получить его, вызвав функцию toSql()
, но в Laravel 8 это будет без привязки.
Incedent::query()->where('column', 'value')->toSql()
Вышеупомянутое приведет к
select * from `incidents` where `column` = ?
DB Query Builder повысил производительность! Спасибо.