【问题标题】:InnoDB frequently updated table running slowInnoDB 频繁更新表运行缓慢
【发布时间】:2012-09-23 01:07:01
【问题描述】:

我有一个非常简单的表格来跟踪用户活动。其结构如下:

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,
)

Table 使用 InnoDB 作为存储引擎。

我的问题

  1. 有什么问题吗?

  2. 我的设计有问题吗?

  3. 在这种特定情况下从哪里开始查找性能问题?

【问题讨论】:

  • 你应该使用 MySQL 分析来看看它为什么工作这么慢。在 MySQL 提示符或其他可视化工具中使用 SET PROFILING = 1; [query here that issues an update]; SHOW PROFILE FOR QUERY 1;,它会显示查询执行的哪一部分花费的时间最多。这种行为可能有几个原因 - 首先也是最明显的是使用默认设置的 InnoDB(增加 innod_buffer_pool)。
  • 您的主索引可能有碎片。删除并重建索引,看看是否有区别。
  • 表格大小为 48Kb,包含少于 1000 条记录。我怀疑 innodb_buffer_pool 与此有关((

标签: mysql sql database-design innodb


【解决方案1】:

嗯,它是 InnoDb,它的性能不如 MyISAM(取决于插入的频率) 您正在尝试在此处实现事件日志记录模型。如果您想生成有用的长期(甚至是中期)统计数据,您的模型将会失败,因为它基本上会忘记上次之前发生的所有事情。 我建议您通过

重新实现
  1. 丢失update on duplicate 子句并简单地为每个活动/事件执行新插入。您减少了更新活动的开销。
  2. 将您的 InnoDb 引擎转换为 MyISAM,性能也得到提升

  3. 如果执行以上两个,PK就变得没有必要了。就目前而言,它的用途值得怀疑。或许您应该立即使用Unique 索引。

所有这一切给您留下的只是一个高效的日志系统,它有能力增长得相当大。有批量归档选项可以进一步处理该问题

【讨论】:

  • 没有必要记录每个活动,而且如果我这样做,数据库将很快增长到数百万条记录。感谢 MyISAM 的建议,但据我所知,这是有问题的:“InnoDB 在写入密集型(插入、更新)表中更快,因为它利用行级锁定并且只保留对正在插入或更新的同一行的更改。 "这就是我首先选择 InnoDB 引擎的原因。
猜你喜欢
  • 1970-01-01
  • 2012-02-20
  • 2014-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多