更新多行Mysql PHP需要很长时间并且崩溃

时间:2019-04-25 09:35:40

标签: php mysql mysqli updates

当用户单击提交按钮时,我想更新数千行,我的函数使用另一个函数来计算要更新的字段。 我的问题是,当我尝试更新几行(例如5或10)时,它工作正常,但是当我更新到20行或更多时,执行代码需要很长时间,有时甚至会显示很多我不知道的错误。没有。 有人可以帮我吗!

我的代码:

//----database connection
/* DATABASE CONFIGURATION */
define('DB_SERVER', 'localhost');
define('DB_PORT', '8090');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_DATABASE', 'db_qvt');

function getDB(){
    $dbhost=DB_SERVER;
    $dbport=DB_PORT;
    $dbuser=DB_USERNAME;
    $dbpass=DB_PASSWORD;
    $dbname=DB_DATABASE;
    // Check connection
    $dbConnection = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
    mysqli_set_charset($dbConnection, "utf8");
     return $dbConnection;
}

//------------ update user final score--------------//
function update_user_final_score($login, $pass_user, $final_score){

  $sql_update="update users_answers set score_final = '$final_score' where login = '$login' and pass_user = '$pass_user'";
  $res = mysqli_query(getDB(), $sql_update);
  return $res;
}

//------------ calculate all users final scores--------------//
function update_all_users_final_score($login){
  $users_client = get_users_answers($login);
  for($i=0;$i<sizeof($users_client);$i++){
    update_user_final_score($users_client[$i]['login'], $users_client[$i]['pass_user'], calculate_user_final_score($users_client[$i]['login'], $users_client[$i]['pass_user']));
  }
}
//-- call the function
update_all_users_final_score($login);

2 个答案:

答案 0 :(得分:4)

您正在使用循环遍历客户端。这意味着您将为每个客户端运行单独的SQL查询。

我相信您应该创建这样的SQL语句:

UPDATE users_answers
SET score_final = (case when login = 'X' then '1'
                        when login = 'Y' then '2'
                        when login = 'Z' then '3'
end);

通过这种方式,您只需要运行一个查询,它比运行多个查询要快得多。

创建具有多个案例的查询的最简单方法是遍历客户端数组,并将案例['when login =“ whatever”然后“ calculated_score”']添加到SQL语句字符串中,然后传递SQL命令字符串到您的mysql服务器。

答案 1 :(得分:1)

我会说这里的问题之一是getDB()函数,该函数很可能在每次被调用时都会创建与数据库的新连接,这显然比使用单个连接要慢。

此外,问题可能是由某些特定的mysql配置选项innodb_flush_log_at_trx_commit引起的。

无论哪种方式,多次插入的最健壮且无错误的方法是使用 prepared语句,将所有插入内容包装在事务中。

所以代码应该是

function update_user_final_score($db, $login, $pass_user, $final_score){

  $sql = "update users_answers set score_final=? where login=? and pass_user=?";
  $stmt = $b->prepare($sql);
  $stmt->bind_param("sss", $login, $pass_user, $final_score);
  $stmt->execute();
}

function update_all_users_final_score($db, $login){
  $users = get_users_answers($login);
  $db->begin_transaction();
  foreach($users as $client){
    $score = calculate_user_final_score($client['login'], $client['pass_user']);
    update_user_final_score($db, $client['login'], $client['pass_user'], $score);
  }
  $db->commit();
}

所以可以这样称呼

$db = getDB();
update_all_users_final_score($db, $login);

关于您收到的错误消息,很可能是由于错误的SQL语法所致,并且也可以通过使用准备好的语句来解决此问题。