2011-08-17 8 views
1

このクエリより簡単になるのですか?セルフ・ジョイン削除クエリが遅くなる

delete a.* from matches a 
    inner join matches b ON (a.uid = b.matcheduid) 

はい、明らかにそれはありません... matchesテーブルが非常に大きい場合上記のクエリのパフォーマンスが本当に悪いですので。

matchesは約220万レコードです。私はこのDELETEクエリが約15,000レコードまでのサイズを取ることを望んでいます。どのようにしてクエリのパフォーマンスを向上させることができますか?私は両方の列にインデックスを持っています。このInnoDBテーブルのUIDとMatchedUIDは唯一の2つのカラムであり、どちらもINT(10)という符号なしタイプです。質問は私のラップトップ(i7プロセッサ)で14時間以上実行されています。

+0

愚かなアイデア:それは 'SELECT'でどんな速さでも解決しますか?その場合は、削除するIDを含むテンポラリテーブルを作成し、それを結合するか、 'IN(サブクエリ)'を使用してより速いかどうか確認してください。 –

+0

他の愚かなアイデア:これらの列にインデックスがありますか? – tdammers

+0

はい、インデックスは両方の列にあります。多分それがDELETEが遅い理由でしょうか? @ダン - 私はあなたの提案を試してみます。 – BMiner

答えて

7

を使用しています私はこれをあなたがこのようにしているなら、得ることができるくらい速いと思う。

本当に2億2000万レコードを削除して、テーブルに15,000レコードしか残らないようにするには、すべてのエントリの99,999%が残っている必要があります。なぜ

  1. 新しいテーブルを作成し、
  2. はちょうどあなたが生き残るためにしたいすべてのレコード、
  3. を挿入し、新しいものと古いものを置き換えますか?このよう

何かが少し速く動作するかもしれません:

/* creating the new table */ 
CREATE TABLE matches_new 
SELECT a.* FROM matches a 
LEFT JOIN matches b ON (a.uid = b.matcheduid) 
WHERE ISNULL (b.matcheduid) 

/* renaming tables */ 
RENAME TABLE matches TO matches_old; 
RENAME TABLE matches_new TO matches; 

この後、あなただけのチェックのみ15.000レコードを扱う場合はかなり高速である必要がありますご希望のインデックスを作成する必要があります。

+0

またはこの紳士が示唆するものをしてください!いい答え! – XIVSolutions

+0

これはほとんど思い知らされません。完璧な答え!クエリが実行されたときにお知らせします。うまくいけば、それは長くかかるべきではありません。:) – BMiner

+0

@BMiner - うん、ねえ?木の森を逃した、私はどのように感じている。 – XIVSolutions

0

ランニングは選択について説明します。*試合からインナーがON bの試合に参加する(a.uid = B。matcheduid)、あなたのインデックスが存在するかを説明するだろうと非常に多くのレコードはしばらく時間がかかることができます削除

0

ここで自分自身を設定しているかもしれませんが、自己結合の最中にこのような削除操作を実行すると、削除ごとに結合インデックスを再計算する必要はありませんか?

それは不格好と強引ですが、あなたはどちらか検討するかもしれない:

A.は、削除をperfoorm THEN、それに参加し、その後、内部から生じたのは、参加UIDを保存するために一時テーブルを作成します。

OR

B. THEN、ブール値(ビット)入力した列を追加フラグを各一致(この操作が高速であるべきであるが)結合を使用し、使用:

DELETE * FROM matches WHERE YourBitFlagColumn = True 

は次にブールを削除しますカラム。

関連する問題