我有一个非常简单的表来跟踪用户活动。它的结构如下:
userId appId lastActivity
PRIMARY(userId, appId)
如果用户在特定应用程序中处于活动状态,则表允许跟踪。它为每个用户每分钟更新一次,并经常阅读以计算特定应用程序中的在线用户数。
最近我注意到,更新需要一段时间才能完成:
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作为存储引擎。
我的问题
有什么问题吗?
我的设计有问题吗?
在这种特定情况下,从哪里开始查找性能问题?
答案 0 :(得分:0)
那么它是InnoDb,它不如MyISAM高(取决于插入的频率) 您正在尝试在此处实现事件日志记录模型。如果您想要生成有用的长期(甚至是中期统计数据),您的模型将会失败,因为它基本上会忘记上一次之前发生的所有事情。
我建议你重新实现update on duplicate
子句,只为每个活动/事件执行一次新插入。您减少了更新活动的开销。将InnoDb引擎转换为MyISAM,性能也有提升
如果执行上述两项,PK将变得不必要。现在看来,它的使用有问题。也许你应该选择一个Unique
索引。
所有这一切离开了你只是一个有效的日志系统,有能力增长相当大。有批处理归档选项可以处理下一行