2017-11-06 19 views
1

テーブル内の各user_id(グループ)に対して、各グループのIDが最も高いレコードを除くすべてのレコードを削除します。これに似た何か:Delete all records except the most recent one?重複レコードを繰り返し削除する

私の場合、それは次のようになります。

DELETE FROM logins 
WHERE user_id IS NOT NULL AND id NOT IN (SELECT MAX(id) FROM logins WHERE user_id IS NOT NULL GROUP BY user_id) 

問題があり、表には100 +ミロンの記録を保持しているので、そのような単一のクエリでこれを行うことは不可能パフォーマンスだろう賢い。

他の方法でこれを行うことができます。いくつかのバッチで?

答えて

0

私はフレーズに傾けられるdeleteよう:これは簡単にlogics(user_id, id)にインデックスを利用することができます

DELETE FROM logins l 
    WHERE l.user_id IS NOT NULL AND 
      l.id <> (SELECT MAX(l2.id) 
        FROM logins l2 
        WHERE l2.user_id = l.user_id 
       ); 

。あなたは、多数の行を削除している場合は、テーブルを切り捨て、再作成することが多い方がよい:

create table temp_logics as 
    select l.* 
    from logins 
    where l.id = (SELECT MAX(l2.id) 
        FROM logins l2 
        WHERE l2.user_id = l.user_id 
       ); 

truncate table logins; 

insert into logins 
    select * from temp_logins; 

あなたがこのアプローチを取る場合は、2番目のテーブルを切り捨てる前にtemp_loginsを検証するようにしてください。実際には、中間テーブルには一時テーブルを使用したくない場合があります。何かがデータベースに発生する可能性があり、データが失われる可能性があるからです。

+0

最初のクエリが私のものと同じように動作していることを確認してください(user_idのグループごとに最大のIDを保持していますか)。また、一度に100万レコードを削除するのに適しているでしょうか? –

+0

@ニルスクリスチャン。 。 。最初のものは全ての 'user_id'のために最大のidを除いて全て削除されます。 –

+0

ありがとうございました。最初にバッチで多くのデータを削除しました。その後、最初のクエリを実行し、+ 2mの行に対して正常に動作しました –

関連する問題