Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 每1小时更新MySQL表中约100万行_Php_Mysql_Codeigniter_Codeigniter 3 - Fatal编程技术网

Php 每1小时更新MySQL表中约100万行

Php 每1小时更新MySQL表中约100万行,php,mysql,codeigniter,codeigniter-3,Php,Mysql,Codeigniter,Codeigniter 3,我使用Codeigniter 3.1.11,有一个问题。我需要通过Cron每1小时更新MySQL表中的大约100万行(将来会更多)。但问题是,若我使用此代码更新了大约200-300行,那个么我的服务器CPU将100%加载,表将在大约200-300行之后停止更新。我甚至必须重新启动服务器上的PHP才能使服务器恢复正常 我做错了什么 如何正确执行此任务,以便快速执行对数据库的查询,并且在服务器上没有繁重的负载 这是来自控制器的代码: 函数cron\u rows\u update(){ $this->

我使用Codeigniter 3.1.11,有一个问题。我需要通过Cron每1小时更新MySQL表中的大约100万行(将来会更多)。但问题是,若我使用此代码更新了大约200-300行,那个么我的服务器CPU将100%加载,表将在大约200-300行之后停止更新。我甚至必须重新启动服务器上的PHP才能使服务器恢复正常

我做错了什么

如何正确执行此任务,以便快速执行对数据库的查询,并且在服务器上没有繁重的负载

这是来自控制器的代码:

函数cron\u rows\u update(){
$this->members\u model->rows\u update();
} 
这是模型中的代码:

函数行\u update(){
$currency\u numbers\u after\u dot=$this->currences\u model->get\u currency('ONE','My currency')['numbers\u after\u dot'];
$game\u currency\u percentage\u max=$this->settings\u model->get\u settings\u details('game\u rating\u percentage\u max')['value'];
$game\u currency\u speed\u in\u hour=$this->settings\u model->get\u settings\u details('game\u currency\u speed\u in\u hour')['value'];
$this->db->from('members');
$query=$this->db->get();
如果($query->num\u rows()>0){
foreach($query->result\u array()作为$row){
$game_total_balance=回合($row['game_vault_balance']+$row['game_available_balance'],$currency_numbers_在点后);
//游戏等级计算
//评级第1部分
//评级第1部分
如果($row['game\u vault\u balance']='0'){
$rating_part1_1='0';
}
如果($row['game\u vault\u balance']>'0'和$row['game\u vault\u balance']<'20'){
$rating_part1_1='0.1';
}
如果($row['game\u vault\u balance']>'20'
和$row['game\u vault\u balance']<'2000'){
$max_game_vault_balance='2000';
$percent=地板($row['game\u vault\u balance']*100/$max\u game\u vault\u balance);
$additional_rating='0.05'*$percent/100;
$rating_part1_1=四舍五入('0.1'+额外_评级,2);
}
如果($row['game\u vault\u balance']>='2000'){
$rating_part1_1='0.15';
}
//评级第1部分2
如果($game\u total\u balance=='0'){
$PER_part1_2='0';
}
如果($game\u total\u balance>'0'和$game\u total\u balance<'20'){
$rating_part1_2='0.1';
}
如果($game\u total\u balance>'20'和$game\u total\u balance<'2000')){
$max_game_total_balance='2000';
$percent=底价($game\u total\u balance*100/$max\u game\u total\u balance);
$additional_rating='0.05'*$percent/100;
$rating_part1_2=四舍五入('0.1'+额外_评级,2);
}
如果($game\u total\u balance>='2000'){
$rating_part1_2='0.15';
}
//评级第1部分第3部分
$rating_part1_3='0';
//评级第1部分4
$PER_part1_4='0';
//评级第2部分
$PER_part2='0';
//评级第3部分
$PER_part3='0';
//计算所有等级
$rating=四舍五入($rating\u part1\u 1+$rating\u part1\u 2+$rating\u part1\u 3+$rating\u part1\u 4+$rating\u part2+$rating\u part3,2);
如果($1级){
$rating_member=楼层($rating);
}
//游戏平衡计算
$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\u balance\u in\u hour\u amount=$amount\u from\u game\u vault\u in\u hour+$new\u balance\u in\u hour;
//更新成员表中的行
如果($game\u total\u balance>'0'){
$this->db->where(“UserID”,$row['UserID']);
$this->db->set(“game\u vault\u balance”,“game\u vault\u balance-”)“$amount\u from\u game\u vault\u in\u hour,FALSE);
$this->db->set(“game\u available\u balance”,“game\u available\u balance+”)“$game\u balance\u in\u hour\u amount,FALSE);
$this->db->set(“评级”,$rating\u成员,FALSE);
$this->db->set(“游戏分级”和“余额”上次更新”,“现在()”,FALSE);
$this->db->update(“成员”);
}
} 
}
返回;
}

尝试限制更新,而不是一次更新所有内容。分块更新

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);
   }

}
您还可以尝试在控制器中使用计时器功能,在一定的时间间隔后触发更新,并如注释中所述增加服务器容量


请阅读更多信息,了解有关高数量记录更新的更多说明,以尽可能快地更新并减少服务器上的负载。

除了您的代码有点混乱之外(
$PER\u part2
$PER\u part3
未使用),我将执行以下操作:

超过100万次迭代后,脚本将无法与
result\u array
一起使用。 原因是,
result\u array
将所有数据存储在一个数组中,迟早会出现内存限制问题

为了避免这种情况,您必须使用
无缓冲行
。 此方法返回单个结果行,而不在内存中预取整个结果

看看他们的文档。(截面无缓冲_行)

接下来我要更改的是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;
}
函数行\u update()
{
$currency\u numbers\u after\u dot=$this->currences\u model->get\u currency('ONE','My currency')['numbers\u after\u dot'];
$game\u currency\u percentage\u max=$this->settings\u model->get\u settings\u details('game\u rating\u percentage\u max')['value'];
$game\u currency\u speed\u in\u hour=$this->settings\u mod
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;
}