【问题标题】:Very slow query on mysql table with 35 million rows对 3500 万行的 mysql 表进行非常慢的查询
【发布时间】:2016-05-16 17:45:38
【问题描述】:

我试图弄清楚为什么我的 MySQL 数据库上的查询如此缓慢。我已经阅读了有关 MySQL 性能的各种内容、各种 SO 问题,但这对我来说仍然是个谜。

  1. 我正在使用 MySQL 5.6.23-log - MySQL Community Server (GPL)
  2. 我有一个大约有 3500 万行的表。
  3. 这个表被插入到大约 5 次/秒
  4. 表格如下所示:

  5. 我对除了 answer_text 之外的所有列都有索引

我正在运行的查询是:

SELECT answer_id, COUNT(1) 
FROM answers_onsite a 
WHERE a.screen_id=384 
 AND a.timestamp BETWEEN 1462670000000 AND 1463374800000 
GROUP BY a.answer_id

这个查询大约需要 20-30 秒,然后给出一个结果集:

有什么见解吗?

编辑

按要求,我的节目创建表:

CREATE TABLE 'answers_onsite' (
  'id' bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  'device_id' bigint(20) unsigned NOT NULL,
  'survey_id' bigint(20) unsigned NOT NULL,
  'answer_set_group' varchar(255) NOT NULL,
  'timestamp' bigint(20) unsigned NOT NULL,
  'screen_id' bigint(20) unsigned NOT NULL,
  'answer_id' bigint(20) unsigned NOT NULL DEFAULT '0',
  'answer_text' text,
  PRIMARY KEY ('id'),
  KEY 'device_id' ('device_id'),
  KEY 'survey_id' ('survey_id'),
  KEY 'answer_set_group' ('answer_set_group'),
  KEY 'timestamp' ('timestamp'),
  KEY 'screen_id' ('screen_id'),
  KEY 'answer_id' ('answer_id')
) ENGINE=InnoDB AUTO_INCREMENT=35716605 DEFAULT CHARSET=utf8

【问题讨论】:

  • 请添加查询的解释输出并列出您在表上的所有索引。您可能没有可以加快查询速度的多列索引。
  • 屏幕截图通常是显示此信息的糟糕方式。你能用那个表的 SHOW CREATE TABLE 的文本内容替换它吗?
  • 更新了我的问题,粘贴了 create table 语句。此外,索引在那里得到了很好的解释
  • 你试过用 > 和
  • 分析表会杀死我的生产环境,正如我所写,这个表有 3500 万行并且每秒被插入多次

标签: mysql


【解决方案1】:
ALTER TABLE answers_onsite ADD key complex_index (screen_id,`timestamp`,answer_id);

【讨论】:

    【解决方案2】:

    你可以像这样使用mysqlPartitioning

    alter table answers_onsite drop primary key;
    alter table answers_onsite add primary key (id, timestamp) partition by HASH(id) partitions 500;
    

    根据表的大小,运行上述操作可能需要一段时间。

    【讨论】:

      【解决方案3】:

      看看你的 WHERE 子句:

      WHERE a.screen_id=384 AND a.timestamp BETWEEN 1462670000000 AND 1463374800000 GROUP BY a.answer_id

      我会创建一个复合索引(screen_id、answer_id、timestamp)并运行一些测试。 您也可以尝试 (screen_id, timestamp, answer_id) 看看它是否表现更好。

      众所周知,BETWEEN 子句很慢,就像任何范围查询一样。数百万行的 COUNT 也是如此。我会每天计算一次并将结果保存到“统计”表中,您可以在需要时查询...显然,如果您不需要实时数据。

      【讨论】:

        猜你喜欢
        • 2010-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-09
        • 2021-07-11
        • 2011-11-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多