当用户单击提交按钮时,我想更新数千行,我的函数使用另一个函数来计算要更新的字段。 我的问题是,当我尝试更新几行(例如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);
答案 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语法所致,并且也可以通过使用准备好的语句来解决此问题。