【发布时间】:2018-05-14 22:59:11
【问题描述】:
所以我有一个相当大的表格,其中包含精细的价格变动(使用 MariaDB)。
CREATE TABLE `table` (
`num` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`pairs` varchar(40) NOT NULL,
`price` decimal(16,10) NOT NULL,
`volume` decimal(22,10) NOT NULL,
PRIMARY KEY (`num`),
KEY `datetime_pairs` (`pairs`,`datetime`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
当数据超过 x 天时,我想按输入的类型计算这些价格的每小时平均值。对于这个例子,我需要 7 天。我想出了这个查询。
SELECT `num`, `datetime`, `pairs`, `price`, `volume`,
AVG(`price`) AS `priceAVG`, AVG(`volume`) AS `volumeAVG`
FROM table
WHERE DATE_FORMAT(`datetime`, '%Y-%m-%d %H:00:00')
< DATE_FORMAT(DATE_SUB(NOW(),INTERVAL 7 DAY), '%Y-%m-%d %H:00:00')
GROUP BY DATE_FORMAT(`datetime`, '%Y-%m-%d %H:00:00'), `pairs`
查询运行大约需要 25 秒。我不认为我可以优化它。 这可能会打印出我正在寻找的结果......但是,一旦我有数据可以使用,我真的不确定回答我的问题的最佳做法是什么。
插入这个结果,并删除旧数据?它会弄乱主键号num,使其与datetime 的排序方式不一致。
使用 SELECT 查询的结果更新旧数据,并删除旧数据减去那些更新的行?这就是我目前正在努力实现的目标......
我认为重复的表可能不是一个选项,因为我有一百个这样的表要处理,而且 cpu 资源也是需要考虑的。我正在使用 cron 和 php 来转换这些查询。我可能每 12 或 24 小时执行一次此操作。
在这种情况下合适的方法是什么?
更新查询是一种现实的处理方式吗?
【问题讨论】:
-
老天,删除对
DATE_FORMAT()的每一个电话。这样做没有世俗的理由,这将是查询需要这么长时间的原因。 -
使用
DATE_FORMAT将阻止 MySQL 使用任何索引。如果除了日期时间之外,您还存储自纪元以来经过的小时数并索引该字段,您将获得更好的性能。这样一来,您最终会在一个整数上进行分组,这会容易得多。
标签: php sql mariadb query-optimization