0

列を持つ私のテーブルで、

id | email     | name
1  | aa@aa.com | aa
2  | aa@aa.com | aaa
3  | bb@b.com  | bb

重複したエントリを削除したいとします。最善の方法は何ですか? (複数のエントリが存在する場合、最初のレコードが保持されます)。また、私のテーブルは40GB以上/数十億のレコードです。

私たちが持っていたオプションは次のとおりです。

1)

ALTER IGNORE TABLE table_name ADD UNIQUE INDEX (email);

4 時間のダウンタイムは手頃な価格ではなかったので、考えられませんでした。

2)

  • group by で削除する必要がある ID を特定し、一時テーブルにプッシュします。
  • ベーステーブルを一時テーブルと内部結合し、行を削除します

これにより、穴とパフォーマンスの問題が発生します。

3)私たちが行った解決策は、

  • 挿入無視オプションを使用してテーブルのダンプを取得しました(負荷を軽減するためにスレーブで行われました)
  • 差分DBにデータを復元
  • テーブルの名前を変更して 2 つのテーブルを交換しました
  • 増分データ変更もコピーされました (ここでダウンタイムが発生しました)。これは、数分のダウンタイムで実行できます。テーブルに更新がなかったので、うまくいきました(挿入しかありませんでした)。

更新もサポートされている場合、最善の解決策は何ですか。私の主な制約はダウンタイムですか?

テーブルを含む更新クエリのログを有効にすることで3を拡張し、復元後に同じことを実行できるかもしれません。

それを行うより良い方法はありますか?

4

1 に答える 1

0

mysqldump を使用して、テーブル全体を "|" であるテキスト ファイルにエクスポートします。分離。

以下のように見えますが、

table.dat

1|aa@aa.com|aa
2|aa@aa.com|aaa
3|bb@b.com|bb

table.dat に 10 億のレコードがあるとします。

  1. table.dat ファイルを 1000 個のサブファイルに分割します。
  2. AWK、SED、SHELL、PERL、または RUBY (私は ruby​​ が大好きです) を使用して、PARALLEL 内の 1000 個のファイルすべてから重複行を削除します。「UNIX のバックグラウンド プロセス」を参照してください。
  3. 1000 個のファイルを 1 つの dat ファイルに統合します。
  4. 重複を再度削除します。 (少し効率が悪い、この部分、考えて最適化します)
  5. 最終的な dat ファイルに重複行がないことを確認してください。

final.dat をテーブルにロードしてください!

これは少し速くなる可能性があります!とにかく最善の道を探すことをやめないでください。

于 2013-03-15T21:04:57.873 に答える