查询失败了,让我陷入困境

时间:2012-10-16 22:28:47

标签: php mysql

我正在尝试执行一个查询,删除过滤器表中不存在的images表中的所有文件。我正在跳过数据库中的3,500个最新文件,以便将表格“修剪”回过滤表中的3,500 +“X”条记录。

过滤器表包含文件的标记,以及images表中使用的文件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的行数:63 php脚本的执行时间:4秒+/- 0.5秒

相关数据库结构

  • 表:图片
  • id
  • url
  • 等...

  • 表:过滤器

  • id
  • img_id(从图像表中包含ID)
  • 等...

2 个答案:

答案 0 :(得分:1)

 for($i=3500; $i<$x; $i++){

如果$x < 3500,则无效。你可能想要:

 for($i=3500; $i<($x + 3500); $i++){

重新阅读有关SQL JOIN的文档也是一个好主意。

答案 1 :(得分:1)

根据布兰登的答案,你可以建立一个subquery。您的整个脚本看起来就像:

$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: %d\n", mysql_affected_rows());

子查询(SELECT `id` from `filter` LIMIT 3500,12340283492834)首先解析并返回父查询的id列表,以便在WHERE子句中使用。然后通过传入一个偏移来保留最后3500行(因此它会跳过前3500行,然后删除其余的行)。请注意丑陋的LIMIT 3500,12340283492834 ...这是因为MySQL不支持无限制的偏移。

完成后,运行一个选择查询以获取所有图像 - 网址,然后循环浏览文件系统上的图像,如果文件名不在结果数组中,则将其删除。