0

ユーザーのアクティビティを追跡するための非常に単純なテーブルがあります。その構造は次のとおりです。

userId appId lastActivity

PRIMARY(userId, appId)

ユーザーが特定のアプリケーション内でアクティブであるかどうかを表で追跡できます。ユーザーごとに 1 分に 1 回更新され、特定のアプリケーション内でオンラインになっているユーザーの数をカウントするために頻繁に読み取られます。

最近、更新の実行に時間がかかることに気付きました。

2012-10-01 16:49:10 - WARN --> Heavy query; array (
  'caller' => 'updateActivity',
  'query' => 'INSERT INTO user_activity VALUES(4953, 1, 1349095750)
                  ON DUPLICATE KEY UPDATE lastActivity = 1349095750',
  'elapsed' => 0.134618,
)
2012-10-01 18:26:06 - WARN --> Heavy query; array (
  'caller' => 'updateActivity',
  'query' => 'INSERT INTO user_activity VALUES(4533, 1, 1349101566)
                  ON DUPLICATE KEY UPDATE lastActivity = 1349101566',
  'elapsed' => 0.581776,
)
2012-10-01 18:27:16 - WARN --> Heavy query; array (
  'caller' => 'updateActivity',
  'query' => 'INSERT INTO user_activity VALUES(5590, 1, 1349101636)
                  ON DUPLICATE KEY UPDATE lastActivity = 1349101636',
  'elapsed' => 0.351321,
)
2012-10-01 20:54:32 - WARN --> Heavy query; array (
  'caller' => 'updateActivity',
  'query' => 'INSERT INTO user_activity VALUES(3726, 1, 1349110472)
                  ON DUPLICATE KEY UPDATE lastActivity = 1349110472',
  'elapsed' => 0.758706,
)

テーブルはストレージ エンジンとして InnoDB を使用します。

私の質問

  1. まったく問題はありませんか?

  2. 私の設計に問題はありますか?

  3. この特定の状況でパフォーマンスの問題を見つけるには、どこから始めればよいでしょうか?

4

1 に答える 1

0

それは InnoDb です。MyISAM ほどパフォーマンスは高くありません (挿入の頻度によって異なります)。ここでイベント ログ モデルを実装しようとしています。有用な長期 (または中期の統計) を生成したい場合、モデルは基本的に前回より前に発生したすべてを忘れてしまうため、失敗します。によって再実装することをお勧めします

  1. 句を失い、update on duplicateアクティビティ/イベントごとに新しい挿入を実行するだけです。更新アクティビティのオーバーヘッドを削減します。
  2. InnoDb エンジンを MyISAM に変換すると、そこでもパフォーマンスが向上します

  3. 上記2つを実行すれば、PKは不要になります。現状では、使用に疑問があります。おそらく、すぐにUniqueインデックスを取得する必要があります。

これで残されるのは、非常に大きくなる能力を持つ効率的なログシステムだけです. さらに先に対処するためのバッチアーカイブオプションがあります

于 2012-10-04T05:31:15.933 に答える