2

MySql テーブルで重複する行を見つけるスクリプトがあります。テーブルには 40,000,000 行が含まれています。しかし、それは非常に遅いです。PHPに出入りせずに重複レコードを見つける簡単な方法はありますか?

これは私が現在使用しているスクリプトです

 $find = mysql_query("SELECT * FROM pst_nw ID < '1000'");
        while ($row = mysql_fetch_assoc($find))
        {
            $find_1 = mysql_query("SELECT * FROM pst_nw add1 = '$row[add1]' AND add2 = '$row[add2]' AND add3 = '$row[add3]' AND add4 = '$row[add4]'");
                if (mysql_num_rows($find_1) > 0) {
                                                    mysql_query("DELETE FROM pst_nw WHERE ID ='$row[ID]'}

         }
4

6 に答える 6

2

通常、このような質問では、問題は「行が重複しているので、1行だけを残したい」です。

ただし、コードから判断すると、「add1、add2、add3、add4のセットが重複している場合は、IDが1000未満のすべてのコピーを削除してください」です。この場合、INSERT IGNOREを使用してテーブルから別のテーブルにコピーしても、目的の処理は実行されません。IDの低い行が保持され、後続の行が破棄される可能性もあります。

すべての「不良ID」を収集するには、このようなものを実行する必要があると思います(重複するID、1000を超える重複。このコードでは「ANDbad.ID <good.ID」を使用したため、ID777を使用している場合ID 888と重複している場合でも、ID 777は削除されます。これが必要ない場合は、「AND bad.ID <1000 AND good.ID> 1000」などで変更できます)。

CREATE TABLE bad_ids AS
    SELECT bad.ID FROM pst_nw AS bad JOIN pst_nw AS good
    ON ( bad.ID < 1000 AND bad.ID < good.ID
       AND bad.add1 = good.add1
       AND bad.add2 = good.add2
       AND bad.add3 = good.add3
       AND bad.add4 = good.add4 );

次に、すべての不正なIDをテーブルに入れたら、

DELETE pst_nw.* FROM pst_nw JOIN bad_ids ON (pst_nw.ID = bad_ids.ID);

パフォーマンスは、add1、add2、add3、add4、およびIDのこの順序での(non_unique、場合によっては一時的な)インデックスから大きな恩恵を受けます。

于 2012-08-19T20:43:28.933 に答える
2

「Group by」演算子を使用して重複行を取得します。試すことができるサンプルは次のとおりです。

select id
 from table
group by matching_field1,matching_field2....
having count(id) > 1

したがって、すべての重複 ID を取得しています。ここで、削除クエリを使用してそれらを削除します。「IN」は「OR」に比べて遅いため、「IN」を使用する代わりに「OR」演算子を使用します。

于 2012-08-19T22:06:27.213 に答える
0

select *を使用せず、比較したい列 (4 つのアドレス) のみを選択すると、コードが改善されます。私のSQLには制限句が必要です。そのような nums 行が大きすぎる場合、応答しない状態を回避できます。

于 2015-07-11T14:18:59.533 に答える