2 回答

TA貢獻1853條經驗 獲得超9個贊
嘗試限制更新而不是一次性更新。分塊更新。
function cron_rows_update() {
? ?$num_of_members = $this->members_model->get_num_of_members();
? ?$limit_per_run = 150;
? ?$total_run = (int)$num_of_members/$per_run;
? ?
? ?for( $i = 0; $i <= $total_run; $i++ ) {
? ? ? $offset = $i * $limit_per_run;
? ? ? $this->members_model->rows_update($offset, $limit_per_run);
? ?}
}
并在rows_update()
function rows_update($offset, $limit_per_run) {
? ??
? ? **
? ? $this->db->limit($offset, $limit_per_run);
? ? $query = $this->db->get();
? ??
? ? $arrUpdateBatchData = [];
? ??
? ? while ($row = $query->unbuffered_row('array'))
? ? {
? ? ? ? // calculations and create array for batch update
? ? }
? ? // update in batch limiting to selected number of records
? ? if (count($arrUpdateBatchData) > 0)
? ? {
? ? ? ? $this->db->update_batch('members', $arrUpdateBatchData, 'UserID');
? ? }
}
您還可以嘗試使用控制器中的計時器功能在一定時間間隔后觸發更新并增加服務器容量,如評論中所述。

TA貢獻2012條經驗 獲得超12個贊
除了您的代碼有點令人困惑($PER_part2
并且$PER_part3
未使用)這一事實之外,我還會執行以下操作:
該腳本將無法運行result_array
超過 100 萬次迭代。原因是,result_array
將所有數據存儲在數組中 - 遲早你會遇到內存限制問題。
為了避免這種情況,你必須使用unbuffered_row
.?此方法返回單個結果行,而不在內存中預取整個結果。
接下來我要改變的是你的 if 塊 - 我將使用if/else
這里的語法。(差別不是很大,但考慮到你的行數 - 它可能會有所幫助)
另外,我外包了您使用相同邏輯兩次計算評級的塊。
基本上以下應該有效:
function rows_update()?
{
? ? $currency_numbers_after_dot = $this->currencies_model->get_currency('ONE', 'My currencty')['numbers_after_dot'];
? ? $game_currency_percentage_max = $this->settings_model->get_settings_details('game_rating_percentage_max')['value'];
? ? $game_currency_speed_in_hour = $this->settings_model->get_settings_details('game_currency_speed_in_hour')['value'];
? ? $this->db->from('members');
? ? $query = $this->db->get();
? ??
? ? $arrUpdateBatchData = [];
? ??
? ? while ($row = $query->unbuffered_row('array'))
? ? {
? ? ? ? $game_total_balance = round($row['game_vault_balance'] + $row['game_available_balance'], $currency_numbers_after_dot);
? ? ? ? if ($game_total_balance > 0) {
? ? ? ? ? ? // Game Rating Calculate
? ? ? ? ? ? // Rating Part1
? ? ? ? ? ? // Rating Part1_1
? ? ? ? ? ? $rating_part1_1 = $this->getRatingPart($row['game_vault_balance']);
? ? ? ? ? ? $rating_part1_2 = $this->getRatingPart($game_total_balance);
? ? ? ? ? ? // Rating part1_3
? ? ? ? ? ? $rating_part1_3 = 0;
? ? ? ? ? ? // Rating part1_4
? ? ? ? ? ? $rating_part1_4 = 0;
? ? ? ? ? ? // Rating part2
? ? ? ? ? ? $PER_part2 = '0';
? ? ? ? ? ? // Rating part3
? ? ? ? ? ? $PER_part3 = '0';
? ? ? ? ? ? // Calculate all rating
? ? ? ? ? ? $rating = round($rating_part1_1 + $rating_part1_2 + $rating_part1_3 + $rating_part1_4 + $rating_part2 + $rating_part3, 2);
? ? ? ? ? ? if ($rating <= 1) {
? ? ? ? ? ? ? ? $rating_member = $rating;
? ? ? ? ? ? }
? ? ? ? ? ? elseif ($rating > 1) {
? ? ? ? ? ? ? ? $rating_member = floor($rating);
? ? ? ? ? ? }
? ? ? ? ? ??
? ? ? ? ? ? // Game balance calculate
? ? ? ? ? ? $amount_from_game_vault_in_hour = $game_currency_speed_in_hour / '100' * $row['game_vault_balance'];
? ? ? ? ? ? $new_balance_in_hour = ($game_currency_percentage_max / '100') * $row['rating'] * $amount_from_game_vault_in_hour;
? ? ? ? ? ? $game_balance_in_hour_amount = $amount_from_game_vault_in_hour + $new_balance_in_hour;
? ? ? ? ? ??
? ? ? ? ? ? $arrUpdateData = [
? ? ? ? ? ? ? ? 'UserID' => $row['UserID'],?
? ? ? ? ? ? ? ? 'game_vault_balance' => ($row['game_vault_balance'] - $amount_from_game_vault_in_hour),
? ? ? ? ? ? ? ? 'game_available_balance' => ($row['game_available_balance'] - $game_balance_in_hour_amount),
? ? ? ? ? ? ? ? 'rating' => $rating_member,
? ? ? ? ? ? ? ? 'game_rating_and_balance_update_last_time' => date('Y-m-d H:i:s')
? ? ? ? ? ? ];
? ? ? ? ? ??
? ? ? ? ? ? $arrUpdateBatchData[] = $arrUpdateData;
? ? ? ? ? ??
? ? ? ? }
? ? ? ??
? ? ? ? if (count($arrUpdateBatchData) > 500)
? ? ? ? {
? ? ? ? ? ? $this->db->update_batch('members', $arrUpdateBatchData, 'UserID');
? ? ? ? ? ? $arrUpdateBatchData = [];
? ? ? ? }? ? ? ?
? ? }
? ??
? ? //update last items
? ? if (count($arrUpdateBatchData) > 0)
? ? {
? ? ? ? $this->db->update_batch('members', $arrUpdateBatchData, 'UserID');
? ? ? ? $arrUpdateBatchData = [];
? ? }
? ? return;? ??
}
function getRatingPart($val)
{
? ? if ($val == 0) {
? ? ? ? $rating_part = 0;?
? ? }
? ? elseif ($val > 0 AND $val < 20)?
? ? {
? ? ? ? $rating_part = '0.1';?
? ? }
? ? elseif ($val > 20 AND $val < 2000)?
? ? {
? ??
? ? ? ? $max_game_vault_balance = 2000;
? ? ? ? $percent = floor($val * 100 / $max_game_vault_balance);
? ? ? ? $additional_rating = 0.05 * $percent / 100;
? ? ? ? ? ?
? ? ? ? $rating_part = round(0.1 + $additional_rating, 2);?
? ? }
? ? else {
? ? ? ? $rating_part = 0.15;?
? ? }
? ??
? ? return $rating_part;
}
- 2 回答
- 0 關注
- 172 瀏覽
添加回答
舉報