0

私は3つのテーブルを持っています、最初はメールアドレスのリストです:

addresses:
id - integer, this is the primary key<br>
email - varchar(255) field holding the address

sent:
sid - integer, foreign key references id in addresses table

received:
rid - integer, foreign key references id in addresses table

明らかに、「送信済み」テーブルと「受信済み」テーブルには他の列がありますが、この質問では重要ではありません。送受信テーブルは、電子メールが送受信されるたびに入力され、アドレスが「アドレス」テーブルにまだ含まれていない場合は追加されます。テーブルはかなり大きくなる可能性があります(100,000以上)。

「送信済み」テーブルと「受信済み」テーブルのエントリは定期的に削除され、さまざまな理由でエントリが削除され、「アドレス」テーブルに孤立したエントリが残ります。

「アドレス」テーブルの孤立したエントリを削除するためのMySQLで最も効率的な方法を探しています。私がこれまでに持っているクエリは次のとおりです。

delete 
from addresses 
where id not in 
         (select rid from received) 
  and id not in 
         (select sid from sent);

これは機能しますが、実行に時間がかかる可能性があり、これを行うための最も効率的な方法ではありません。私もこれを試しました:

delete 
from addresses 
where not exists 
      (select 'x' from sent where sent.sid=addresses.id) 
  and not exists 
      (select 'x' from rceieved where recieved.rid=addresses.id);

これは少し速かったですが、それでも長い時間がかかります。JOIN構文を使用する必要があると思いますが、この時点でSQLの知識が不足しています。

4

4 に答える 4

1

これはトリックを行う必要があります

DELETE adresses.* FROM adresses 
LEFT JOIN sent ON sent.sid=adresses.id
LEFT JOIN received ON received.rid=adresses.id
WHERE sent.sid IS NULL AND received.rid IS NULL
于 2012-07-12T10:21:28.257 に答える
0

これを試してください:s.idがnullである(a.sentid = s.id)に送信された左結合をアドレスから削除します

于 2012-07-12T10:17:53.933 に答える
0

申し訳ありませんが、明確な答えを出すことができません。しかし、私も同様の問題を抱えていました。周りを見回した後、主な選択肢は2つしかないようです。

  1. を使用してWHERE x NOT IN y
  2. を使用してLEFT JOIN x ON y WHERE z IS NULL

それぞれ2822291レコードと916626レコードの2つのテーブルを比較して、両方の方法を試しました。

パフォーマンスの結論は次のとおりです。

  • タイプ1はタイプ2よりも大幅に高速です(600秒対6000秒)
  • インデックスまたはキーは、両方のタイプでこの操作のパフォーマンスに妥当な影響を及ぼします。
  • パフォーマンスは、実際のDISTINCT値の数とはほとんど関係ありません。したがって、2000個の異なる値または両方のテーブルの15個を比較するには、ほぼ同じ時間がかかります。

したがって、結論として、現時点(2013年8月)では、オプション1の方がまだ速い方法であるように思われます。使用NOT EXISTSはさらに高速になる可能性がありますが、タイプ1と比較してパフォーマンスの変化は劇的ではありません。

これが最終的に誰かを助けることを願っています。

于 2013-08-21T09:11:41.347 に答える
0

2つのid列(および他のいくつかの同一でない列)を含む2つの300kmyisamテーブルを使用していくつかのテストを行いました。IDは、1つのテーブルに2つのレコードがあることを除いて同一でした。これらのIDを見つけるために言及された3つの方法を試しました:

存在しない場所

左参加

の ()

SQL_NO_CACHEを使用し、すべてのクエリが同じように実行されることを確認すると、サーバーは2つの結果を約14.6秒で返しました。

上記の違いは、キャッシュ、mysqlのバージョンの違い、および/または一般的なサーバー構成のいずれかである必要があります。

于 2016-08-18T15:47:15.390 に答える