-1

フィルタテーブルに存在しない画像テーブルからすべてのファイルを削除するクエリを実行しようとしています。テーブルを「トリム」してフィルターテーブルのレコード数を3,500+「X」に戻すために、データベース内の最新のファイルを3,500スキップしています。

フィルタテーブルには、ファイルのマーカーと、画像テーブルで使用されるファイル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秒

関連するDB構造

  • 表:画像
  • id
  • url
  • 等...

  • 表:フィルター

  • id
  • img_id(画像テーブルからのIDを含む)
  • 等...
4

2 に答える 2

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

の場合、これは何もしません$x < 3500。あなたはおそらく欲しかった:

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

SQLに関するドキュメントを読み直すのJOINも良い考えです。

于 2012-10-16T22:39:24.027 に答える
1

ブレンダンの答えを基に、サブクエリを作成するだけです。スクリプト全体は次のようになります。

$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が制限なしのオフセットをサポートしていないためです。

完了したら、selectクエリを実行してすべてのimages-urlsを取得し、ファイルシステム上の画像をループして、ファイル名が結果の配列にない場合はそれらを削除します。

于 2012-10-16T22:41:14.067 に答える