MySQL:查询时间序列中某个日期之前的最后一个值的最佳实践

标签 mysql select query-optimization

我在 MySQL 中有下表:

CREATE TABLE `history` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `code` CHAR(32) NOT NULL,
    `value` FLOAT NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE INDEX `timestamp_code` (`timestamp`, `code`),
    INDEX `code` (`code`),
    INDEX `timestamp` (`timestamp`)
   ) COLLATE='utf8_general_ci' ENGINE=InnoDB;

我想知道为了最有效地访问特定代码集在特定日期之前的最后一个可用值的最佳实践是什么?

到目前为止,我提出了以下查询:

SELECT h.* FROM history h
JOIN (
    SELECT code, MAX(timestamp) as 'last_ts'
    FROM history WHERE
    timestamp < '2015-09-04 13:50:00' AND
    code IN ('119813249', '12087792', '12087797',
    '127012151', '131014335', '131014378',
    '132757371', '15016059', '15016062',
    '150250238', '153462747', '155802712',
    '156974389', '162277696', '166330444',
    '166483001', '167220356', '167264923',
    '167867931', '172283682', '177539478',
    '177583937', '177648754', '177649011',
    '187532416', '189230667', '70273253',
    '70342790', '79342386', '82460282',
    '98693280', '98693380')
    GROUP BY code) last_price
ON last_price.last_ts = h.timestamp
AND last_price.code = h.code

上面的查询可以工作,但随着表中条目数量的增加(100'000'000 行)而变得缓慢。

您可以下载sample data填充表格。

最佳答案

通过代码、时间戳创建索引 - 而不是时间戳、代码。这将使 mysql 在查找每个代码的最大时间戳之前对代码进行排序 - 并且应该更快。使用说明来验证索引是否已使用。

如果您创建该索引 - 您不必修改您的查询。

关于MySQL:查询时间序列中某个日期之前的最后一个值的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32484728/

相关文章:

php - MYSQL 查询中的两次计数

c# - 安全软件许可证检查/验证

mysql获取包含20位长十进制数的两个字段之间的数字

php - 什么是我的查询获得快速结果的好索引?

mysql - 为什么 IN() 被视为 O(logN) 操作?

mysql - 如果在其他列上查询,则获取用计数填充的计数总和 - 到右侧的最后一列

mysql - 多列索引对单列也有用吗?

mysql - Where 条件 Mysql 中的 CSV

mysql - 根据同一表上的两列选择单列的总和

mysql - 如果我杀死一个巨大的 MySQL InnoDb DELETE 查询会发生什么?