使用表扫描的查询不佳有时会在MariaDB上花费数小时

时间:2018-11-13 18:30:05

标签: mysql mariadb

我的应用程序使用了我试图保持隔离的MariaDB数据库,但是一个特定的用户直接进入该数据库,并在6周后立即开始抱怨,但没有发现他们的查询速度从5分钟开始变慢(我认为这很糟糕)足够)超过120分钟。

从那时起,今天它有时和往常一样快,有时又变慢了。

这是他们的查询:

SELECT MAX(last_updated) FROM data_points;

这是表格:

CREATE TABLE data_points (
  seriesId INT UNSIGNED NOT NULL,
  modifiedDate DATE NOT NULL,
  valueDate DATE NOT NULL,
  value DOUBLE NOT NULL,
  created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  last_updated DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP()
    ON UPDATE CURRENT_TIMESTAMP,
  id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  CONSTRAINT pk_data PRIMARY KEY (seriesId, modifiedDate, valueDate),
  KEY ix_data_modifieddate (modifiedDate),
  KEY ix_data_id (id),
  CONSTRAINT fk_data_seriesid FOREIGN KEY (seriesId)
  REFERENCES series(id)
) ENGINE=InnoDB
  DEFAULT CHARSET=utf8mb4
  COLLATE=utf8mb4_unicode_ci
  MAX_ROWS=222111000;

这是说明:

id      select_type     table       type    possible_keys   key     key_len ref     rows    Extra
1       SIMPLE          data_points ALL     NULL            NULL    NULL            NULL    224166191

该表大约有2.5亿行,并且增长速度相对较快。

我可以强迫用户做一些更明智的事情,但是从短期来看,我很想知道为什么查询持续6周后,今天的查询持续时间会变得疯狂。我会接受第一个可以解释这一点的答案。

1 个答案:

答案 0 :(得分:1)

SELECT MAX(last_updated) FROM data_points;易于优化:

INDEX(last_updated)

该索引将使MAX本质上是瞬时的。而且它将避免破坏磁盘和缓存(请参见下文)。

两件事控制着未编入索引的速度:

  • 表格的大小“正在相对快速增长”,并且
  • [这可能是您要寻找的。]运行查询时,缓存了多少表。这会使速度相差10倍。您可以这样部分测试此声明:

重新启动mysqld;时间查询再次计时。第一次运行不得不打很多磁盘(因为重新启动);第二个可能已经在RAM中找到了所有内容。

另一件事可能会扰乱时间:如果运行其他“大”查询,并且该表的块超出缓存,那么查询将再次变慢。

相关性:表的大小,innodb_buffer_pool_size的值和RAM的数量。

关于一个不相关的主题... PRIMARY KEY (seriesId, modifiedDate, valueDate)似乎很奇怪。 PK必须是唯一的。日期(日期时间等)可能在同一天/秒有多个条目;这样可以确定唯一性吗?特别是两个日期?

(更多)

请说明4个日期中每个日期的含义。并问问自己是否全部需要。 (表的大部分是这些日期!)

该表有一个AUTO_INCREMENT;其他桌子需要它吗?如果不是,则可以将其删除,或者将其用于确保PK是唯一的。

为了更好地为您提供帮助,我们需要查看更多查询。