我的应用程序使用了一个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
这张table有大约2.5亿行,而且增长相对较快。
我可以强迫用户做一些更明智的事情,但在短期内,我很想理解为什么查询持续时间在平静了6周之后变得疯狂。我会接受第一个可以解释的答案。
1条答案
按热度按时间5n0oy7gb1#
SELECT MAX(last_updated) FROM data_points;
易于优化:这个指数会使
MAX
基本上是瞬间的。它将避免对磁盘和缓存的重击(见下文)。有两个因素控制未索引的速度:
表的大小,“增长相对较快”,以及
[这可能是您正在搜索的内容。]运行查询时缓存了多少表。这会使速度相差10倍。您可以通过以下方式部分测试此声明:
重启mysqld;查询时间;再来一次。第一次运行对磁盘的影响很大(因为重新启动);第二个可能在拉姆找到了一切。
另一件会影响计时的事情是:如果运行其他某个“大”查询并将此表的块从缓存中移出,那么查询将再次变慢。
相关性:表的大小
innodb_buffer_pool_size
,以及ram的数量。在一个无关的主题上。。。那个
PRIMARY KEY (seriesId, modifiedDate, valueDate)
看起来很奇怪。pk必须是唯一的。日期(datetime等)可能在同一天/秒有多个条目;所以你能确定它的独特性吗?尤其是两次约会?(更多)
请解释这4个日期的含义。问问自己是否都需要(大约一半的table都是这些日期!)
这张table有一张table
AUTO_INCREMENT
; 其他table需要吗?如果没有,那么它要么可以被删除,要么可以用来确保pk是唯一的。为了更好地帮助您,我们需要查看更多的查询。