Имеется таблица users и таблица payments
А так же страница с партнерской программой
Система группирует статистику пользователя по партнерской программе, т.е. зашел пользователь на страницу партнерской программы, система достает из таблицы его реферальный код и ищет пользователей в таблице users, которые активировали у себя этот код (способом перебора), как только найдены такие пользователи система с помощью того же перебора ищет записи каждого, кто использовал этот код в таблице payments и суммирует сумму платежей. Далее эта сумма передается изначальному пользователю и он получается статистику и соответственно свой уровень в реферальной программе.
Все это дело очень замедляет загрузку страницы ( из-за всех запросов страница загружается больше 5 секунд ). Нужно как то оптимизировать код, чтобы максимально ускорить загрузку страницы. Не представляю как изменить запросы, чтобы их упростить
Код:
$ref_users = User::where('invite', $user->ref_code)->get();
$all = 0;
foreach($ref_users as $ref){
$all += Func::ref_deposited($ref->user_id);
}
$level = Func::getLevel($all);
Функция получения суммы всех платежей:
static function ref_deposited($user_id){
$all = 0;
$payments = PaySys::where('user_id', $user_id)->where('status', 1)->sum('amount');
$payments2 = PaySys2::where('user_id', $user_id)->where('status', 'complete')->sum('amount');
$deposits = TradeLog::where('user_id', $user_id)->where('status', 'success')->sum('amount');
$all = $payments + $payments2 + $deposits;
return round($all, 2);
}
Функция получения уровня:
static function getLevel($sum){
$sum = Func::convertToUsd($sum);
if($sum >= 0 && $sum < 500){
$value['level'] = 1;
$value['perc'] = 5;
$value['refer'] = 0.30;
$value['toNext'] = 500;
}elseif($sum >= 500 && $sum < 2000){
$value['level'] = 2;
$value['perc'] = 6;
$value['refer'] = 0.40;
$value['toNext'] = 2000;
}elseif($sum >= 2000 && $sum < 5000){
$value['level'] = 3;
$value['perc'] = 7;
$value['refer'] = 0.45;
$value['toNext'] = 5000;
}elseif($sum >= 5000 && $sum < 7500){
$value['level'] = 4;
$value['perc'] = 8;
$value['refer'] = 0.60;
$value['toNext'] = 7500;
}elseif($sum >= 7500 && $sum < 10000){
$value['level'] = 5;
$value['perc'] = 9;
$value['refer'] = 0.65;
$value['toNext'] = 10000;
}elseif($sum >= 10000){
$value['level'] = 6;
$value['perc'] = 10;
$value['refer'] = 0.70;
$value['toNext'] = 99999;
}
return $value;
}
Попробуйте создать справочник уникальных кодов и сумм по этому коду, навесив на него индексирование. Если я правильно понимаю, в данной задаче нет необходимости определения пользователей, которые тоже использовали этот код, нужна лишь сумма. Так? При таком раскладе пользователь не будет ожидать расчетов. А сами расчеты будут выполняться отдельно от сессии пользователя.
Или, возможно, есть доп.ограничения на временные интервалы? Тогда можно использовать партицирование(partition) таблицы payments по дате, и последующее наложение фильтров на даты в запросе поиска. Это сузит границы поиска.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей