MySQL:SUM/MAX/MIN GROUP BY 查询优化

标签 mysql sql optimization group-by

我有一张比特币交易表:

    CREATE TABLE `transactions` (
      `trans_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `trans_exchange` int(10) unsigned DEFAULT NULL,
      `trans_currency_base` int(10) unsigned DEFAULT NULL,
      `trans_currency_counter` int(10) unsigned DEFAULT NULL,
      `trans_tid` varchar(20) DEFAULT NULL,
      `trans_type` tinyint(4) DEFAULT NULL,
      `trans_price` decimal(15,4) DEFAULT NULL,
      `trans_amount` decimal(15,8) DEFAULT NULL,
      `trans_datetime` datetime DEFAULT NULL,
      `trans_sid` bigint(20) DEFAULT NULL,
      `trans_timestamp` int(10) unsigned DEFAULT NULL,
      PRIMARY KEY (`trans_id`),
      KEY `trans_tid` (`trans_tid`),
      KEY `trans_datetime` (`trans_datetime`),
      KEY `trans_timestmp` (`trans_timestamp`),
      KEY `trans_price` (`trans_price`),
      KEY `trans_amount` (`trans_amount`)
    ) ENGINE=MyISAM AUTO_INCREMENT=6162559 DEFAULT CHARSET=utf8;

从 AUTO_INCRMENT 值可以看出,该表有超过 600 万条条目。最终还会有更多。

我想查询该表以获得任意时间间隔内的最高价格、最低价格、交易量和交易总额。为了实现这一点,我使用如下查询:

    SELECT 
    DATE_FORMAT( MIN(transactions.trans_datetime),
        '%Y/%m/%d %H:%i:00'
        ) AS trans_datetime,
    SUM(transactions.trans_amount) as trans_volume,
    MAX(transactions.trans_price) as trans_max_price,
    MIN(transactions.trans_price) as trans_min_price,
    COUNT(transactions.trans_id) AS trans_count 
    FROM 
    transactions
    WHERE
    transactions.trans_datetime BETWEEN '2014-09-14 00:00:00' AND '2015-09-13 23:59:00'
    GROUP BY 
    transactions.trans_timestamp DIV 86400

这应该选择一年内进行的交易,按天(86,400 秒)分组。

这个想法是时间戳字段,它包含与日期时间相同的值,但作为时间戳...我发现这比 UNIX_TIMESTAMP(trans_datetime) 更快,除以我想要在时间间隔中的秒数.

问题:查询速度很慢。我的处理时间超过 4 秒。这是 EXPLAIN 的结果:

    id  select_type table   type    possible_keys   key key_len ref rows    Extra
    1   SIMPLE  transactions    ALL trans_datetime,trans_timestmp   NULL    NULL    NULL    6162558 Using where; Using temporary; Using filesort

问题:是否可以更好地优化它?这种结构或方法有缺陷吗?我尝试了几种方法,但只成功地获得了微弱的毫秒级增益。

最佳答案

表中的大部分数据都是过去 12 个月的数据?那么你需要触摸 table 的大部分吗?那么就没有办法加快查询速度。但是,您可以更快地获得相同数量级的输出...

创建汇总表。它将有一个DATE作为PRIMARY KEY,并且这些列将实际上是SELECT中提到的字段。

一旦您最初填充了汇总表,就可以通过每晚为当天的事务添加新行来维护它。 More in my blog .

然后,获取所需输出的查询将命中此汇总表(只有几百行),而不是具有数百万行或行的表。

关于MySQL:SUM/MAX/MIN GROUP BY 查询优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32581606/

相关文章:

sql - 什么会导致合法的 MySql INSERT INTO 命令失败?

java - 用于 H2 AUTO_INCRMENT PK 的 JOOQ 代码生成器,带有 japAnnotations

php - 如何将带有php的下拉菜单的值传递给数据库

sql - firebird 数据库查询中 '.' 运算符的用途是什么?

database - 初始化对象或直接从数据库读取/写入数据库效率更高吗?

java - 在 StringBuffer append 中对单字符值使用字符而不是 String

mysql - AVG*COUNT 返回浮点值

MySQL复杂排名查询

mysql - 多个sql连接同一个表

c++ - 是否有任何 C++ 编译器能够优化 lround(pow(sqrt(i), 2)) 现在或在不久的将来用 i 替换它?