我的应用程序使用了我试图保持隔离的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周后,今天的查询持续时间会变得疯狂。我会接受第一个可以解释这一点的答案。
答案 0 :(得分:1)
SELECT MAX(last_updated) FROM data_points;
易于优化:
INDEX(last_updated)
该索引将使MAX
本质上是瞬时的。而且它将避免破坏磁盘和缓存(请参见下文)。
两件事控制着未编入索引的速度:
重新启动mysqld;时间查询再次计时。第一次运行不得不打很多磁盘(因为重新启动);第二个可能已经在RAM中找到了所有内容。
另一件事可能会扰乱时间:如果运行其他“大”查询,并且该表的块超出缓存,那么查询将再次变慢。
相关性:表的大小,innodb_buffer_pool_size
的值和RAM的数量。
关于一个不相关的主题... PRIMARY KEY (seriesId, modifiedDate, valueDate)
似乎很奇怪。 PK必须是唯一的。日期(日期时间等)可能在同一天/秒有多个条目;这样可以确定唯一性吗?特别是两个日期?
(更多)
请说明4个日期中每个日期的含义。并问问自己是否全部需要。 (表的大部分是这些日期!)
该表有一个AUTO_INCREMENT
;其他桌子需要它吗?如果不是,则可以将其删除,或者将其用于确保PK是唯一的。
为了更好地为您提供帮助,我们需要查看更多查询。