php - mysql - 删除有限制的大量行(php nightly cron)

标签 php mysql delete-row sql-delete

不确定处理此问题的最佳方法是什么。对于我的特殊情况,我有很多表,我想删除时间戳大于 3 个月前的任何行...也就是只保留最近 3 个月的记录。

非常简单,就像这样:

//set binding cutoff timestamp
$binding = array(
    'cutoff_time' => strtotime('-3 months')
);

//##run through all the logs and delete anything before the cutoff time

//app
$stmt = $db->prepare("
    DELETE
    FROM app_logs           
    WHERE app_logs.timestamp < :cutoff_time
");
$stmt->execute($binding);

//more tables after this

我要删除的每个表都有一个已索引的时间戳列。我担心当要删除的行数很大时。限制循环中的 block 的最佳实践是什么?我能想到的就是进行初始选择以查找是否有任何需要删除的行,然后运行删除(如果有)...重复直到初始找不到任何结果。这会为循环的每次迭代添加一个额外的计数查询。

这里的标准/推荐做法是什么?

编辑:

快速写下我的想法

//set binding cutoff timestamp
$binding = array(
    'cutoff_time' => strtotime('-3 months')
);

//set limit value
$binding2 = array(
    'limit' => 1000
);

//##run through all the logs and delete anything before the cutoff time

//get the total count
$stmt = $db->prepare("
    SELECT
        COUNT(*)
    FROM app_logs
    WHERE app_logs.timestamp < :cutoff_time
");
$stmt->execute($binding);

//get total results count from above
$found_count = $stmt->fetch(PDO::FETCH_COLUMN, 0);

// loop deletes
$stmt = $db->prepare("
    DELETE
    FROM app_logs           
    WHERE app_logs.timestamp < :cutoff_time
    LIMIT :limit
");

while($found_count > 0)
{
    $stmt->execute( array_merge($binding, $binding2) );

    $found_count = $found_count - $binding2['limit'];
}

最佳答案

这取决于您的表大小及其工作负载,因此您可以尝试一些迭代:

  1. 只需删除超过 3 个月的所有内容即可。看看时机是否足够好。是否存在性能下降或表锁?您的应用如何处理数据删除期?

  2. 如果一切都不好,请考虑删除 10k 左右的限制。按照上面的方法检查一下。添加适当的索引

  3. 即使它仍然很糟糕,请考虑在删除之前选择 PK,而不是在 PK 上删除 10k 限制并在查询之间暂停。

  4. 还是很糟糕?添加新列“要删除”,并按照上述所有要求对其进行操作。

旋转 table 有很多技巧。尝试一些东西,你就会面对你的需求

关于php - mysql - 删除有限制的大量行(php nightly cron),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28288216/

相关文章:

MySQL 表结构 - 存储一组有限的数字

php - 多文件上传支持所有浏览器,特别是ie7,ie8和ie9

ms-access - 使用 acCmdDeleteRecord 删除 MS Access 中连续表单上的记录

php - HTML 按钮在 Wordpress 中无法在移动设备上运行

php - 为什么 Firefox 提示下载 POST 到的文件?

javascript - 如何在datepicker函数中传递php参数

mysql - 为 Apache 修改 DYLD_LIBRARY_PATH? Perl CGI 脚本在连接到 MySQL 时不起作用

sql - 在“代替删除”触发器中删除记录

php - 删除与用户名相关的行

javascript - PHP json_encode 在字符串末尾加一个1