【问题标题】:MySQL Process taking unusually huge timeMySQL进程花费异常大量时间
【发布时间】:2015-07-19 09:39:50
【问题描述】:

我有一个每小时运行的任务,现在已经运行了几个月。该过程从 MySQL (MariaDB) 获取分析并聚合数据。通常需要 1-5 分钟才能完成。

但是,从 13 小时前开始,现在突然需要 26 分钟。我重新启动了 MySQL 服务器,没有任何改变。进程列表显示聚合需要很长时间(有些查询需要 500 秒才能完成,而过去不到 30 秒)。

我要查询的表有 2600 万行。

是什么导致了处理时间的突然跳跃?好久没用了!

你建议我现在做什么?数据库是否已损坏?

查询:

*************************** 2. row ***************************
      Id: 76042556
    User: -----
    Host: --------
      db: mydb
 Command: Query
    Time: 456
   State: Sending data
    Info: SELECT avg(analytics.event) AS `avg_session`, count(*) AS `count` FROM `analytics` WHERE `analytics`.`app_id` = '436' AND `analytics`.`event_type` = 'session' AND `analytics`.`created_at` >= '2015-06-19 12:16:41' AND `analytics`.`created_at` <= '2015-07-19 12:16:41' ORDER BY `analytics`.`id` ASC
Progress: 0.000

解释:

EXPLAIN EXTENDED SELECT `analytics`.`event` AS `event`, `analytics`.`created_at` AS `a_created_at`, EXTRACT(DAY FROM analytics.created_at) AS `interval`, count(analytics.id) AS `count` FROM `analytics` WHERE `analytics`.`app_id` = '436' AND `analytics`.`event_type` = 'startup' AND `analytics`.`created_at` >= '2015-06-21 09:32:41' AND `analytics`.`created_at` <= '2015-07-21 09:32:41' GROUP BY `interval` ORDER BY `a_created_at` ASC
    -> ;
+------+-------------+-----------+------+---------------+--------+---------+-------+----------+----------+----------------------------------------------+
| id   | select_type | table     | type | possible_keys | key    | key_len | ref   | rows     | filtered | Extra                                        |
+------+-------------+-----------+------+---------------+--------+---------+-------+----------+----------+----------------------------------------------+
|    1 | SIMPLE      | analytics | ref  | app_id        | app_id | 5       | const | 15236882 |   100.00 | Using where; Using temporary; Using filesort |
+------+-------------+-----------+------+---------------+--------+---------+-------+----------+----------+----------------------------------------------+

P.S:请不要告诉我如何减少长查询,而是帮助我理解这个具体问题。

【问题讨论】:

  • 您可以在这里发布您的查询吗?
  • 查询已添加
  • 您的innodb_buffer_pool_size 值是多少?可能是 MariaDB 无法将数据集放入内存中,并且正在使用磁盘来查找它应该聚合的记录——在数据库世界中做某事的时间异常长,几乎总是意味着它们受到 I/O 限制。在机械磁盘的情况下,这意味着您的设置会变得像蜗牛一样慢,以至于手动计算东西几乎更快。一定要验证您的数据是否适合内存,如果可能(而您没有)- 尝试使用 SSD 作为永久存储,而不是机械驱动器。

标签: mysql


【解决方案1】:

我觉得你可以试试:

  • 优化表
  • 修复表 - 实际上数据可能已损坏,或者可能存在一些过载
  • 检查锁:可能在表上执行了更多插入操作 由聚合查询查询(可能某些功能已 最近添加,用户更频繁地提交表单...)

我假设索引已明确定义,并且数据库结构未在您不知情的情况下由其他人更新;)

【讨论】:

  • 我用的是InnoDB引擎,所以没有修复功能,只有dump和restore。
  • 啊 - 好的 - 所以也许这会有所帮助(如果表损坏是问题的根源......):percona.com/blog/2008/07/04/recovering-innodb-table-corruption
  • 我怎么知道它是否已损坏?是否有一个状态变量来表明这一点?因为一切正常(除了刚刚发生的 5x 查询时间)
  • status 变量 - 我认为不是 ;) 但是将其复制到 myisam 并在其上运行查询,应该会给您一些比较,并且可能会导致一些线索...是该查询唯一的突然开始变得越来越长,然后就在那张桌子上?这是现在唯一导致该表出现问题的查询吗?您确定在查询变慢之前没有更改任何内容吗?顺便提一句。我看到您添加了解释结果 - 但解释的查询与有问题的查询不同 - 为什么?
  • 还有一件事:它总是这样的日期范围吗?如果从到日期/时间相同,您可以设置 analytics.created_at = '{datetime}' 而不是检查范围 - 并且(如上面建议的那样)尝试删除订单
【解决方案2】:

一些建议

  1. 删除 Order by 子句,因为它对此查询没有任何好处
  2. 根据您的数据性质添加适当的索引。可能是app_id
  3. 如果在analytics 中触发了太多更新/删除,则执行optimize table analytics。这将重新构建您的索引

如果您也发布您的explain 结果将对我们有所帮助

【讨论】:

  • 我添加了解释并优化了表格。优化并没有解决问题。
  • app_id 上的索引似乎对您没有帮助。因此,您可以尝试创建 app_id、event_type、created at 的复合索引。这将为您提供最大的性能。但是,如果您经常插入,您将面临一些问题。你配置好你的 innodb 缓冲池大小了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-10
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多