【发布时间】:2020-07-21 08:35:58
【问题描述】:
我使用 Codeigniter 3.1.11 并有一个问题。我需要每 1 小时通过 Cron 更新 MySQL 表中的大约 100 万行(将来会更多)。但问题是,如果我使用此代码更新超过约 200-300 行,我的服务器 CPU 已加载 100%,并且表在约 200-300 行后停止更新。而且我什至必须重新启动服务器上的 PHP 才能使服务器恢复正常。
我做错了什么?
如何正确地完成这个任务,以便快速执行对数据库的查询,并且不会对服务器造成太大的负载。
这是来自控制器的代码:
function cron_rows_update() {
$this->members_model->rows_update();
}
这是来自模型的代码:
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();
if($query->num_rows() > 0) {
foreach($query->result_array() as $row) {
$game_total_balance = round($row['game_vault_balance'] + $row['game_available_balance'], $currency_numbers_after_dot);
// Game Rating Calculate
// Rating Part1
// Rating Part1_1
if ($row['game_vault_balance'] == '0') {
$rating_part1_1 = '0';
}
if ($row['game_vault_balance'] > '0' AND $row['game_vault_balance'] < '20') {
$rating_part1_1 = '0.1';
}
if ($row['game_vault_balance'] > '20'
AND $row['game_vault_balance'] < '2000') {
$max_game_vault_balance = '2000';
$percent = floor($row['game_vault_balance'] * 100 / $max_game_vault_balance);
$additional_rating = '0.05' * $percent / 100;
$rating_part1_1 = round('0.1' + $additional_rating, 2);
}
if ($row['game_vault_balance'] >= '2000') {
$rating_part1_1 = '0.15';
}
// Rating Part1_2
if ($game_total_balance == '0') {
$PER_part1_2 = '0';
}
if ($game_total_balance > '0' AND $game_total_balance < '20') {
$rating_part1_2 = '0.1';
}
if ($game_total_balance > '20' AND $game_total_balance < '2000') {
$max_game_total_balance = '2000';
$percent = floor($game_total_balance * 100 / $max_game_total_balance);
$additional_rating = '0.05' * $percent / 100;
$rating_part1_2 = round('0.1' + $additional_rating, 2);
}
if ($game_total_balance >= '2000') {
$rating_part1_2 = '0.15';
}
// Rating part1_3
$rating_part1_3 = '0';
// Rating part1_4
$PER_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;
}
if ($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;
// Update row in members table
if ($game_total_balance > '0') {
$this->db->where("UserID", $row['UserID']);
$this->db->set("game_vault_balance", "game_vault_balance - " . $amount_from_game_vault_in_hour, FALSE);
$this->db->set("game_available_balance", "game_available_balance + " . $game_balance_in_hour_amount, FALSE);
$this->db->set("rating", $rating_member, FALSE);
$this->db->set("game_rating_and_balance_update_last_time", 'NOW()', FALSE);
$this->db->update("members");
}
}
}
return;
}
【问题讨论】:
-
如果服务器在 200 或 300 个查询时出现故障,那么您应该增加
server容量或查询数量。 -
检查您的服务器错误日志。分享您的服务器配置,我们或许可以为您提供帮助。
-
@BasheerKharoti 我尝试将我的服务器扩展到 32GB RAM 和 8 个 CPU,结果是一样的。我想我可能不应该使用 foreach 并且需要其他方法来加载我的服务器很少?
-
使用 shuf 可能吗?
-
@Hack5 你是什么意思?在哪里使用 shuf?
标签: php mysql codeigniter codeigniter-3