大表的更新超时没有错误

时间:2017-08-30 17:01:10

标签: php mysql sql

我遇到了一个脚本问题,该脚本应该使用另一个表中另一个日期字段的值填充日期字段。 (正在填充的表包含超过1.82亿条记录)脚本在大约一小时左右后停止运行而不会产生任何错误。我已经尝试添加我能想到的所有超时异常,但无济于事。 (我必须使用动态设置,因为我无法访问数据库服务器来更改.ini设置)任何人都可以让我知道出了什么问题?这是我的代码,非常感谢任何帮助。

<?php
$dbname = "rismedia_newsletter";
include('db_connect.php');
ignore_user_abort(1);
set_time_limit(0);
ini_set('mysql.connect_timeout', 28800);
ini_set('default_socket_timeout', 28800);
ini_set('max_execution_time', 0);
ini_set('max_input_time', -1);
ini_set('memory_limit', -1);

$sql = "SELECT `ad_stats`.`id`, `newsletters`.`send_date` 
        FROM ad_stats 
            INNER JOIN newsletters ON (`ad_stats`.`newsletter_id` = `newsletters`.`id`) 
        WHERE `ad_stats`.`send_date` IS NULL 
           OR send_date = '0000-00-00 00:00:00' 
        GROUP BY `ad_stats`.`newsletter_id`";

$res = $db -> query($sql);
while ($row = $res -> fetch_assoc()) {
    $id = $row['id'];
    $send_date = $row['send_date'];
    if ($send_date > '') {
        $qupd = "UPDATE ad_stats SET send_date = '".$send_date."' WHERE id= ".$id;
        $upd = $db -> query ($qupd);
    } else { 
        continue; 
    }
}
?>

1 个答案:

答案 0 :(得分:2)

我想说你应该将它们组合成一个查询以加快处理速度。

MySQL的:

UPDATE 
    ad_stats a 
    JOIN newsletters b ON a.newsletter_id = b.id 
SET 
    a.send_date = b.send_date 
WHERE 
    a.send_date IS NULL OR 
    a.send_date = '0000-00-00 00:00:00'

Postgres的:

UPDATE
    ad_stats
SET
    send_date = N.send_date
FROM
    ad_stats A
    INNER JOIN newsletters N ON A.newsletter_id = N.id
WHERE
    A.send_date IS NULL OR 
    A.send_date = '0000-00-00 00:00:00'

这种方式应该更快但是如果它在一段时间后仍然失败,那么它可能是服务器设置,你说你可能无法改变。如果是这种情况,您可能必须使用LIMIT以较小批量运行脚本并多次运行,直到完成为止。它也可能有助于确保您拥有ad_stats.newsletter_id和newsletters.id的索引。