Как оптимизировать скорость этой консольной команды Laravel

Вот консольная команда, которую я написал в Laravel, и мне было интересно, как я могу сделать ее лучше и быстрее? Что я сделал не так?

И если вы можете представить мне книгу, чтобы я мог лучше разбираться в алгоритмах и писать лучший код, я был бы признателен.

Спасибо

$process = Process::create([
    'started_at'    => now()
]);

//set how many subscription to get from db in each iteration 
//we use this for loop to prevent memory exhaustion
$subscriptionsCountPerIteration  = 1000;
$subscriptionsCount = Subscription::count();
$numberOfIterations = $subscriptionsCount/$subscriptionsCountPerIteration;

for($i=0; $i < $numberOfIterations; $i++){
    $subscriptions = Subscription::query()->limit($subscriptionsCountPerIteration)->offset($subscriptionsCountPerIteration * $i)->get();

    foreach($subscriptions as $subscription){
        $subscription->updateStatus($process);
    }
}

$process->finished_at = now();
$process->save();

Я думаю, что то, что у меня есть две петли, - плохая идея.

Вложенные циклы выглядят так, как будто они нужны только для того, чтобы разбить большой процесс на сегменты. Циклы — это плохо, когда вы постоянно просматриваете одни и те же данные, чего здесь нет (AFAIK).

Nigel Ren 26.11.2022 09:38

Покажите свой метод updateStatus

Vlad 26.11.2022 14:38
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я считаю, что один вложенный цикл в этом случае неизбежен, потому что иначе обновление не может быть выполнено в пакетном режиме. Однако у Laravel есть собственный функционал для этого, о котором можно прочитать здесь. Я предлагаю вам проверить, использовать ли chunk() или chunkById(), потому что эти две функции обрабатывают пакет по-разному.

Ответ принят как подходящий

Вы можете «оптимизировать» скорость выполнения команды, запустив логику updateStatus() внутри задания . Это означает, что команда будет асинхронно отправлять новое задание для проверки состояния и быстро возвращаться, поскольку фактическая логика выполняется в рабочей очереди.

Это будет выглядеть примерно так:

foreach($subscriptions as $subscription){
    CheckSubscriptionStatusJob::dispatch($subscription->id);
}

Примечание. Фактическая проверка статусов по-прежнему будет занимать столько же времени, но команде не нужно будет ждать завершения проверки. Кроме того, вы можете использовать несколько очередей для параллельного выполнения нескольких заданий.

Другие вопросы по теме