Я создаю приложение, которое обрабатывает несколько тысяч квартир в месяц.
Это означает несколько вставок, обновлений и выборок в разных таблицах на квартиру в месяц.
Я использовал встроенный синтаксис laravel / eloquent, ничего в raw sql, так как я не очень хорошо с ним знаком.
У меня есть кнопка, которая генерирует информацию за месяц для всех квартир. Я не был очень рад тому, что все это было в одном действии, но это требовалось от меня.
Теперь, каждый раз, когда я нажимаю кнопку и генерирую информацию, она становится все труднее обрабатывать по мере заполнения базы данных каждый месяц. Я предполагаю, что это нормально, учитывая ситуацию. Могу ли я получить совет о том, как это оптимизировать? Я должен ждать, как 30 секунд — 1 минута, чтобы закончить …. что не хорошо …
Вот как в основном работает мой контроллер (это основная функция хранения, которая вызывает несколько других функций):
// define month
$month = '01-04-2017';
// identify all payment categories (like water, electricity, maintenance etc)
// all these must be treated separately as they are calculated in very different ways
$payment_categories = PaymentCategories::get();
$payments_array = [];
foreach($payment_categories as $payment_category){
$total = Transactions::where('month', $month)->where('payment_category_id', $payment_category->id)->sum('amount');
$payments_array[$payment_category->id] = $total;
}
$apartments = Apartments::get();
foreach($apartaments as $apartment){
$this->storeMainData($apartment);
// each of these categories must be treates separately as they are calculated in very different ways
foreach($payment_categories as $payment_category){
$total_amount = $payments_array[$payment_category->id];
if($payment_category->id == '1'){
$this->storePaymentCategory1($apartment, $payment_category, $month, $total_amount);
}
// there are aprox. 10 categories of payments which dont have a common pattern so they must be treated separately
// these functions below work similarly to storePaymentCategory1()
if($payment_category->id == '2'){
$this->storePaymentCategory2($apartment, $payment_category, $month, $total_amount);
}
if($payment_category->id == '3'){
$this->storePaymentCategory3($apartment, $payment_category, $month, $total_amount);
}
if($payment_category->id == '4'){
$this->storePaymentCategory4($apartment, $payment_category, $month, $total_amount);
}
// ...
// NEXT I HAVE A FUNCTION FOR GENERATING THE PDF RECEIPT
// NEXT I HAVE ANOTHER FUNCTION TO GENERATE THE INVOICE, IF THE APARTMENT REQUIRES ONE
}
}
Далее у меня есть функция storeMainData ():
$validator = Validator::make(Input::all(), MainData::$rules, MainData::$messages);
if($validator->passes()){
$check = MainData::where('month', $month)->where('apartament_id', $apartament->id)->first();
if(count($check)>0){
$store_main_data = $check;
}
else{
$store_main_data = new MainData;
}
//main data stuff (like apartment receipt data etc...)
$store_main_data->save();
}
else{
return Redirect::back()
->withErrors($validator);
}
Далее у меня есть функция storePaymentCategory1 () (которая является примером того, как работают и другие категории платежей):
// NOW WE MUST APPLY: total amount stored in the payment category / apartment percentage = due payment for the apartment;
// identify the percentage
$percentage_type = $payment_category->percentage_id;
$percentage = Percentages::where('percentage_type_id', $percentage_type)->where('apartment_id', $apartment->id)->first();
// verify if the percentage type is applied to this apartment
$calculated_apartments = Percentages::where('percentage_type_id', $percentage_type)->get();
$calculated_apartments_array = [];
foreach($calculated_apartments as $calculated_apartment){
array_push($calculated_apartments_array, $calculated_apartment->apartment_id);
}
if(in_array($apartment->id, $calculated_apartments_array)){
$validator = Validator::make(Input::all(), DuePayments::$rules, DuePayments::$messages);
if($validator->passes()){
$check = DuePayments::where('month', $month)->where('apartment_id', $apartment->id)->where('payment_category_id', $payment_category->id)->first();
if(count($check)>0){
$store_due_payment = $check;
}
else{
$store_due_payment = new DuePayments;
}
// store due payment stuff
$store_due_payment->save();
}
else{
return Redirect::back()
->withErrors($validator);
}
}
Задача ещё не решена.
Других решений пока нет …