我正在尝试执行一个查询,该查询从图像表中删除过滤器表中不存在的所有文件。我跳过了数据库中的 3,500 个最新文件,以便将表"修剪"回过滤器表中的 3,500 + "X"记录量。
筛选器表包含文件的标记,以及图像表中使用的文件 ID。
代码将在 cron 作业上运行。
我的代码:
$sql = mysql_query("SELECT * FROM `images` ORDER BY `id` DESC") or die(mysql_error());
while($row = mysql_fetch_array($sql)){
$id = $row['id'];
$file = $row['url'];
$getId = mysql_query("SELECT `id` FROM `filter` WHERE `img_id` = '".$id."'") or die(mysql_error());
if(mysql_num_rows($getId) == 0){
$IdQue[] = $id;
$FileQue[] = $file;
}
}
for($i=3500; $i<$x; $i++){
mysql_query("DELETE FROM `images` WHERE id='".$IdQue[$i]."' LIMIT 1") or die("line 18".mysql_error());
unlink($FileQue[$i]) or die("file Not deleted");
}
echo ($i-3500)." files deleted.";
输出:删除了 0 个文件。
数据库内容:
images table: 10,000 rows
filters table: 63 rows
筛选器表中包含图像表 ID 的行数:63php 脚本的执行时间:4 秒 +/- 0.5 秒
相关数据库结构
- 表:图像
- 编号
- 网址
等。。。
表:过滤器
- 编号
- img_id(包含图像表中的 ID)
- 等。。。
Brendan的答案,你可以构建一个子查询。您的整个脚本可能如下所示:
$query = mysql_query(
"DELETE FROM `images` WHERE `id` NOT IN (
SELECT `id` from `filter`
) ORDER BY `id` DESC LIMIT 3500,12340283492834
") or die(mysql_error());
printf("Files deleted: %dn", mysql_affected_rows());
子查询首先(SELECT `id` from `filter` LIMIT 3500,12340283492834)
解析,并将 id 列表返回到父查询以在 WHERE
子句中使用。然后,通过传入偏移量来保留最后 3500 行(因此它会跳过前 3500 行,然后删除其余行)。请注意丑陋的LIMIT 3500,12340283492834
...这是因为MySQL不支持无限制的偏移量。
完成后,运行选择查询以获取所有图像 url,然后遍历文件系统上的图像,如果文件名不在结果数组中,则删除它们。
for($i=3500; $i<$x; $i++){
如果$x < 3500
,这将不执行任何操作。您可能想要:
for($i=3500; $i<($x + 3500); $i++){
重新阅读有关 SQL JOIN
的文档也是一个好主意。