1

このクエリよりも簡単ですか?

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

matchesはい、明らかにそうです...テーブルが非常に大きい場合、上記のクエリのパフォーマンスは非常に悪いためです。

matches約 2 億 2000 万レコードです。この DELETE クエリにより、サイズが約 15,000 レコードに減少することを願っています。クエリのパフォーマンスを向上させるにはどうすればよいですか? 両方の列にインデックスがあります。UID と MatchedUID は、この InnoDB テーブルの 2 つの列のみであり、どちらも INT(10) 型であり、符号なしです。ラップトップ (i7 プロセッサ) でクエリが 14 時間以上実行されています。

4

4 に答える 4

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 レコードのみを処理する場合にはかなり高速になるはずです。

于 2011-08-17T06:00:26.597 に答える
0

Explain select a.* from matches a inner join matches b ON (a.uid = b.matcheduid) を実行すると、インデックスがどのように存在し、使用されているかが説明されます

于 2011-08-17T06:00:00.497 に答える
0

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

それは不格好で強引ですが、次のいずれかを検討してください。

A. 内部結合の結果の uid を格納するための一時テーブルを作成し、そのテーブルに結合してから、削除を実行します。

また

B. ブール (ビット) 型の列を追加し、結合を使用して各一致にフラグを付けます (この操作は FAST である必要があります)。次に、次を使用します。

DELETE * FROM matches WHERE YourBitFlagColumn = True

次に、ブール列を削除します。

于 2011-08-17T06:01:53.717 に答える
0

おそらく、削除をバッチ処理する必要があります。これは、共通テーブル式を使用して再帰的な削除を行うか、バッチ サイズで反復処理するだけで実行できます。

于 2020-08-28T21:14:05.830 に答える