0

、およびのCalls3 つの列を持つテーブルがあります。messageTypecallIdlastModified

呼び出しごとに、メッセージごとに 1 行ずつ、合計 4 行が DB に書き込まれます。メッセージには、 CALL -SETUPCALL-PROGRESSCALL-STARTCALL-STOP (コード 4)の 4 種類があります。

messageTypecallId主キーを構成します。

次の行を削除したい:

  • 終了した通話に対応する行。CALL-STOP メッセージが DB に書き込まれると、通話が終了します。
  • 4 時間以降変更されていない行 (たとえば)。

次のクエリを使用しました。

DELETE FROM Calls WHERE callId IN (SELECT * FROM (SELECT DISTINCT callId FROM Calls WHERE messageType=4 OR TIMESTAMPDIFF(SECOND,lastModified,NOW()) > 14400) AS tmp);

このステートメントは、テーブルをクリーンアップするためだけに使用します。しかし同時に、テーブルは を使用して大きなファイル (約 30000 行) によって非常に頻繁に (たとえば毎秒)LOAD DATA INFILEデータが取り込まれます。データのロードのみとデータのロード + クリーンの間のパフォーマンスの違いが実際にわかります。

パフォーマンスを向上させるにはどうすればよいですか? SQL DELETE で? DB自体に?

私はMySQLを使用していると正確に言います。

ありがとう

4

1 に答える 1

0

あなたのためのいくつかの考え:

1) 私は DISTINCT が大嫌いです。各呼び出しには、4 の messageType が 1 つだけありますか? その場合、OR 句の変更部分に DISTINCT を使用しています。これはどう:

 WHERE messageType = 4
 OR (messageType = 1 and lastModified < datesub(now(), interval 4 hour)

(したがって、返される ID は 1 つだけであり、それらを区別する必要はありません)。

2) 日付列で数式を実行しないでください - エンジンはインデックスを使用できません! 数式を反対側に移動する方法については、上記の WHERE 句を参照してください。ここでは、インデックスを使用でき、定数値をキャッシュできます。

3) インデックスを記述していませんが、おそらく (lastModified、messageType、callId) に複合インデックスが必要です。

4) 他の人が述べているように、エンジンの選択は重要です。myisam はすべてをロックします。innodb を試してください。

5) 場合によっては、MySQL が大きな範囲の日付の日付インデックスを好まないことがあります。スクリプトを使用して小さなバッチを削除してみてください。

幸運を!

于 2012-09-10T21:00:59.843 に答える