【问题标题】:Insert Bulk Data in the DB in Background in PHP [duplicate]在PHP的后台在数据库中插入批量数据[重复]
【发布时间】:2020-11-28 15:57:02
【问题描述】:

我有一个向客户发送批量消息的表单,点击提交按钮后,它会在发送前将消息保存在数据库中,但插入过程大约需要 2 分钟才能插入 3000 条记录,如何减少插入时间或如何在后台处理数据以避免用户等待该过程完成。我已经尝试了几个关于堆栈溢出的选项,但都没有成功。我在共享主机上。 这是我的代码

<?php
if(isset($_POST['submit'])){
 $date = date("D, F d, Y h:i:sa");
 $phones = $_POST['recipient_phones']; //get phone numbers from textarea
 $phones = trim($phones,",\r\n\t\r\n/\s+/\0\x0B]/"); //do some regex
 $phones = multiexplode(array(","," ","\n","r\n",".","|",":"),$phones);//reformat and convert to array
 $sender = $_POST['sender_id']; //Get Sender ID input field
 $message = $_POST['message']; //Get Message input field
 $time = $_POST['sc_time']; //Get time input field



 ob_end_clean();
 ignore_user_abort();
 ob_start();
 header("Connection: close");
 // echo json_encode($out);
 header("Content-Length: " . ob_get_length());
 ob_end_flush();
 flush();



foreach($phones as $phone){

      $data = array("sender" => "$sender","phone" => "$phone", "message" => "$message", "user_id" => "$user_id","time_submitted" => "$date");
   
         $qry = Insert('crbsms_queue',$data);
  
   
   $_SESSION['msg']="10";

  echo "<script>location.href='$url?success=yes';</script>";
   exit
}



     # Insert Data 
    function Insert($table, $data){
    global $mysqli;
    //print_r($data);

    $fields = array_keys( $data );  
    $values = array_map( array($mysqli, 'real_escape_string'), array_values( $data ) );
    
   //echo "INSERT INTO $table(".implode(",",$fields).") VALUES ('".implode("','", $values )."');";
   //exit;  
    mysqli_query($mysqli, "INSERT INTO $table(".implode(",",$fields).") VALUES ('".implode("','", $values )."');") or die( mysqli_error($mysqli) );

}

【问题讨论】:

  • 警告:您对SQL Injections 持开放态度,应该使用参数化的prepared statements,而不是手动构建查询。它们由PDOMySQLi 提供。永远不要相信任何形式的输入!即使您的查询仅由受信任的用户执行,you are still in risk of corrupting your dataEscaping is not enough!
  • 请记住,您在问题中发布的代码存在多个问题,包括语法错误
  • 这里是更正,对吗: $stmt = $connect->prepare("INSERT INTO tbl (sender,phone,message,user_id,time_submitted) VALUES(:sender, :phone, :消息, :user_id, :time_submitted)"); $stmt->bindValue(':sender', $sender); $stmt->bindValue(':phone', $phone); $stmt->bindValue(':message', $message2); $stmt->bindValue(':user_id', $user_id); $stmt->bindValue(':time_submitted', $date); $stmt->执行();
  • 是的,它使用的是PDO库,比mysqli好。我的回答显示了如何使用 mysqli
  • 天哪,不。 trim($phones,",\r\n\t\r\n/\s+/\0\x0B]/") 真是一团糟。那绝对不是如何包装角色面具。请阅读trim() 文档,以更好地了解第二个论点没有按照您的想法执行。

标签: php mysqli bulkinsert


【解决方案1】:

插入 3000 行并不多,如果操作得当,应该不会花费太多时间。您必须记住,您应该始终使用准备好的语句。您可以使用不同的数据多次执行相同的语句。当你将整个事情包装在一个事务中时,它应该执行得非常快。

// Start transaction
$mysqli->begin_transaction();

// prepared statement prepared once and executed multiple times
$insertStatement = $mysqli->prepare('INSERT INTO crbsms_queue(sender, phone, message, user_id, time_submitted) VALUES(?,?,?,?,?)');
$insertStatement->bind_param('sssss', $sender, $phone, $message, $user_id, $date);
foreach ($phones as $phone) {
    $insertStatement->execute();
}

// Save and end transaction
$mysqli->commit();

如果这不能提高性能,则意味着您在其他地方遇到了问题。您需要分析和调试您的应用程序以找出问题的根源。

旁注:记得enable mysqli error reporting,否则您的交易可能无法正常运行。

【讨论】:

    猜你喜欢
    • 2021-10-27
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多