Задать вопрос
@Hfnas

Как сделать пакетную обработку в laravel?

Проблема, у меня этот код выполняется целый день.... не может нормально 1000 записей обработать. Ребят вы знаете, в чем проблема, и куда копать....
Есть ли инструменты вроде пакетной обработки , как в случае доктрины https://www.doctrine-project.org/projects/doctrine... ?
public function getLead($all=false)
    {        
        $filter = new LeadsFilter();
        $filter->setLimit(100); //было 250

        $leads = [];

        try {
            $leads[] = $this->apiClient->leads()->get($filter, [LeadModel::CONTACTS]);
            AmoLeadModel::import($leads,$this->crmCompanyID,$constants);
            $i = 2;
            //разбивка по страницам
            while ($leads[0]->getNextPageLink() != null) {
                $filter->setPage($i);
                $leads[] = $this->apiClient->leads()->get($filter, [LeadModel::CONTACTS]);
                TestLeadModel::import($leads,$this->crmCompanyID,$constants);
                $i++;
            }
        } catch (AmoCRMApiNoContentException $exception) {
            Log::error(__METHOD__ . ' setLead:' . $exception->getMessage());
        }
    }


<b>class TestLeadModel</b>
 public static function import(array $rows, $companyID, $constants=[])
    {
foreach ($rows as $row) {
    $entity = TestLead::firstOrNew(['crmCompanyID'=>$companyID,'TestID' => $row->getId()]);

                if ($entity->TestID === null) {
                    $entity->TestID = $row->getId();
                }

                $entity->name = $row->getName();
                $entity->isExist = 1;
                $entity->created = $row->getCreatedAt();
                $entity->updated = $row->getUpdatedAt();
                $entity->crmCompanyID=$companyID;

                $success=0;

                $comment = null;
                $manager = null;


                if ($row->getStatusId()) {
                    $TestStatusEntity = TestStatus::firstOrNew(['crmCompanyID'=>$companyID,'TestID' => $row->getStatusId()]);
                    if ($TestStatusEntity->TestID===null){
                        $TestStatusEntity->TestID=$row->getStatusId();
                        $TestStatusEntity->crmCompanyID=$companyID;
                        $TestStatusEntity->save();
                    }

                    $entity->crmTestStatusID = $TestStatusEntity->id;

                    if ($row->getStatusId() == 142 || $row->getStatusId() == 143) {
                        $entity->closed = date('Y-m-d H:i:s', $row->getClosedAt());
                    }
                }

                $entity->price = $row->getPrice();
                $contacts = $row->getContacts();

                if (isset($contacts[0])) {
                    $TestContactEntity = TestContact::firstOrNew(['crmCompanyID'=>$companyID,'TestID' => $contacts[0]->getId()]);
                    if ($TestContactEntity->TestID===null){
                        $TestContactEntity->TestID=$contacts[0]->getId();
                        $TestContactEntity->crmCompanyID=$companyID;
                        $TestContactEntity->save();
                    }

                    $entity->crmTestContactID = $TestContactEntity->id;
                }else{
                    $entity->crmTestContactID = null;
                }

                if (isset($contacts[1])) {
                    $TestContactEntity = TestContact::firstOrNew(['crmCompanyID'=>$companyID,'TestID' => $contacts[0]->getId()]);
                    if ($TestContactEntity->TestID===null){
                        $TestContactEntity->TestID=$contacts[0]->getId();
                        $TestContactEntity->crmCompanyID=$companyID;
                        $TestContactEntity->save();
                    }

                    $entity->crmTestContact2ID = $TestContactEntity->id;
                }else{
                    $entity->crmTestContact2ID = null;
                }

                $customFields = $row->getCustomFieldsValues();

                $mainUserField = $row->getResponsibleUserId();
                if ($mainUserField!= null) {
                    $TestUserEntity = TestUser::firstOrNew(['crmCompanyID'=>$companyID,'TestID' => $mainUserField]);

                    if ($TestUserEntity->TestID===null){
                        $TestUserEntity->TestID=$mainUserField;
                        $TestUserEntity->crmCompanyID=$companyID;
                        $TestUserEntity->save();
                    }

                    $entity->crmTestUserID = $TestUserEntity->id;
                }

                if ($customFields != null) {
                    $commentField = $customFields->getBy('fieldId', $constants["TestLeadCommentID"]);
                    if ($commentField != null) {
                        $comment = $commentField->getValues()[0]->getValue();
                    }

                    $managerField = $customFields->getBy('fieldId', $constants["TestLeadUserID"]);
                    if ($managerField != null) {
                        $managerName = $managerField->getValues()[0]->getValue();
                        $manager = TestUser::where('crmCompanyID',$companyID)->where('name', 'LIKE', "%$managerName%")->first();
                        if($manager!=null){
                            $manager=$manager->id;
                        }
                    }

                    $successField = $customFields->getBy('fieldId', $constants["TestLeadDealID"]);
                    if ($successField != null) {
                        $successName = $successField->getValues()[0]->getValue();
                        if ($successName == 'Да') {
                            $success = 1;
                        }
                    }
                }

        
                $entity->comment = $comment;
                $entity->crmTestUser2ID = $manager;
                $entity->isExist = 1;
                $entity->isSuccess = $success;
                $entity->save();

}
}


Индекс поставила на crmCompanyID,TestID
  • Вопрос задан
  • 89 просмотров
Подписаться 1 Простой 2 комментария
Пригласить эксперта
Ответы на вопрос 2
ThunderCat
@ThunderCat
{PHP, MySql, HTML, JS, CSS} developer
Ребят вы знаете, в чем проблема, и куда копать....
Нет конечно... Берете код, бьете на блоки, расставляете метки времени, отчет по затраченному времени пишете в лог. Проблемные места смотрите и решаете можете ли уменьшить время исполнения. Вангую что самые тормоза у вас будут на выборке из бд или на запросах к апи. В случае бд - вывести запрос и сделать explain. По результату уже можно будет что-то советовать. В случае тормозов с апи - тут уже ничего в плане оптимизации сильно не придумаешь, но в любом случае задачи лучше будет скинуть в очередь и уже оттуда они будут выполняться, пока не закончится список. Кроме того, выборка по одной записи из бд в цикле - классическая ошибка, нужно объединить все запросы в один через join или in(), а дальше работать с полученным массивом.
Ответ написан
Davidaa_WoW
@Davidaa_WoW
Основная проблема - это обращение к БД в цикле, каждый раз. Помимо долгого ожидания Вы так и БД перегружаете.
Для пакетной обработки не нужно никаких отдельных инструментов и библиотек. Вы просто собираете все данные в локальный массив, устанавливаете предел обработки пачки, после достижения предела делаете ОДИН запрос в БД.
Если у Вас идёт обращение к разным таблицам, то можно либо JOIN-ами выводить нужные данные, если таблицы пересекаются, либо отдельно готовить под каждую таблицу свой массив для выборки.

Если предел размерности у Вас небольшой, допустим 100 элементов, то там и на пачки разбивать не обязательно. Всё, что Вам нужно сделать - это вынести из цикла все обращения к БД, оставив только подготовку данных, для дальнейших запросов
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы