2017-08-10 7 views
0

私は、データを取得する多くのイベントを持つ大きなテーブルで作業しています。重複のための単一のイベント内の特定の列(textまたはvarchar)現時点ではテーブルに100,000を超える行があり、問題のイベントに属する約30,000行があるため、サブクエリとの結合には数分かかることがあります。MySQLは効率的に大きなテーブルに重複をマークします

これまで私がこれまで思いついたのはこれです。それは動作しますが、まだ完了までに数秒かかるので、私はより効率的なソリューションを学びたいと思います。また、この比較的簡単な作業では、大きすぎて醜い感じがします。

DROP TEMPORARY TABLE IF EXISTS table2 
; 
CREATE TEMPORARY TABLE table2 AS (SELECT * FROM table WHERE ide = 123) 
; 
DROP TEMPORARY TABLE IF EXISTS table3 
; 
CREATE TEMPORARY TABLE table3 AS (SELECT id,odpoved FROM table 
    WHERE ide = 123 
    GROUP BY text_column 
    HAVING COUNT(*) > 1) 
; 
UPDATE (
    SELECT all.id id FROM table3 txt 
    INNER JOIN table2 all ON all.text_column = txt.text_column 
) a 
INNER JOIN table main ON main.id = a.id 
SET main.duplicity = 1 

これは現在、約8秒かかります。イベントのデータ量は、少なくとも3倍になると思います。

既存のデータベースまたはテーブル構造を変更することはできません。

私の以前のアプローチ - よりよいが、現在のデータセットには約4分かかった:あなたが持っているどのように多くの重複レコードを気にしないので、あなたが重複を見つけるためにサブクエリでexistsを使用することができます

UPDATE table t1 
JOIN (
    SELECT id,text_column FROM table 
    WHERE ide = 123 
    GROUP BY text_column 
    HAVING COUNT(*) > 1) t2 
ON t1.text_column = t2.text_column 
SET t1.duplicity = 1 
+0

この重複データはどのくらいの頻度でアクセスしますか?頻繁ではない場合は、実際のクエリが入力されたときに計算を実行するだけです。いずれの場合も、重複したデータはいつでも失効する可能性があります。 –

+0

データのインポート後に1日に1回これを行います。しかし、他のアプリケーションやユーザーに依存しているため、システムを長持ちさせることができません。私はシステムのピーク使用時にこれを行う必要があります。クエリが実行されている間、他の要求に対する応答は停止します。 – LuH

+0

また、データが古くなってしまったらどういう意味ですか? – LuH

答えて

1

:あなたがtext_columnide、およびidフィールド上のマルチカラムインデックスを持っている場合

UPDATE table t1 
SET t1.duplicity = 1 
WHERE ide = 123 
    AND EXISTS (SELECT 1 FROM table t2 WHERE t1.text_column=t2.text_column and t1.id<>t2.id and ide=123) 

はまた役立ちます。

+0

これは実行不可能です - 現在のデータセットでは、9分の処理後に私はそれを殺しました。あなたは多列インデックスで何かにいる可能性がありますが、残念ながらa)私はテーブルを変更することはできませんし、b)異なるイベントは異なる列に彼らのおそらくユニークなデータを置くので、テキスト、またはid-ide-textのトリプルを使用すると、挿入や更新のパフォーマンスが低下する可能性があります。私はここでしか推測していない。 – LuH

+0

私はユニークなインデックスについては言及していませんでしたが、クエリをスピードアップできるインデックスです。 – Shadow

+0

私は重複しているかどうかを確認しているデータのように、おそらくユニークなデータを意味していました。 – LuH

関連する問題