将数据发送到数据库超过最大执行时间 30 秒



我像这样用AJAX从JS向PHP发送数据:

$.ajax({ type: "POST", url: 'protected_page.php', data: JSON.stringify(distances), contentType: "application/json" });

数据"距离"是结构化的 - {id1:Array(95),id2:Array(95)...}。它有 95 个 ID,每个 id 都有 95 个整数值 witch 表示距离(基本上是一个 95x95 矩阵)。

数据需要插入到我的表中u_id | i_id1 | i_id2 | distance。下面是这样做的 PHP 方法,但它超过了 30 秒的最大执行时间,并且 ~10 000 行中只有 ~700 行到达数据库。我应该更改数据库的结构,还是可以以某种方式使其更优化?

function postDistances2($mysqli){
 if ( getenv("REQUEST_METHOD") !== "POST" ) return;
 if ( $distance = json_decode(file_get_contents("php://input"),true) ) {
    $keys = [];
    $user_id = $_SESSION['user_id'];
    foreach ($distance as $key => $value) {
        array_push($keys,$key);
    }
    foreach($distance as $key=>$value){
        for($i=0;$i<sizeof($value);$i++){
            if ($insert_stmt = $mysqli->prepare("INSERT INTO image_distances (u_id, i1_id, i2_id, distance) VALUES (?, ?, ?, ?)")) {
            $insert_stmt->bind_param('iiid', $user_id, $key, $keys[$i], $value[$i]);
            // Execute the prepared query.
            $insert_stmt->execute(); 
            }
        }
    }
 }

}

你应该只调用prepare一次。这就是它的重点,真的。仅绑定参数并从循环内执行。我怀疑这会加快速度,但可能还不够。

我认为处理此问题的最佳方法是批量发送 JSON。请记住,您的服务器可能会在某个时候遇到重负载,因此批处理应该相当小。页面上的进度指示器可能适合此处。

另一种选择是构建单个SQL查询,例如(?, ?, ?, ?),(?, ?, ?, ?),(?, ?, ?, ?)。这将最大限度地减少脚本与数据库服务器通信所花费的时间。

另一种选择是禁用最大执行时间。我当然根本不推荐这个,但它仍然是一种选择。

最新更新