mysql中的多重移动平均

mysql中的多重移动平均,mysql,moving-average,Mysql,Moving Average,我必须在mysql中的数据集上计算移动平均值(不同时段)。我尝试了两种方法来计算平均值,但这两种方法都需要相当长的时间。分享下面的代码 方法:-1 select t1.*, (select avg(t2.last_price) from temp_data t2 where t2.rownum>t1.rownum-50 and t2.rownum<=t1.rownum and t1.script_code=t2.script_code)

我必须在mysql中的数据集上计算移动平均值(不同时段)。我尝试了两种方法来计算平均值,但这两种方法都需要相当长的时间。分享下面的代码

方法:-1

select t1.*, 
    (select avg(t2.last_price) 
        from temp_data t2 
        where t2.rownum>t1.rownum-50 and t2.rownum<=t1.rownum and t1.script_code=t2.script_code) as 'ma_small_price'
from temp_data t1;
rownum是具有连续行号的列。ID是主键,但不是连续的,所以我必须添加一个单独的列

示例数据的链接:

接下来,我必须并行计算同一数据上的多个移动平均值,但是周期(在上面的代码中指定为50)是不同的

我的数据集庞大且不断增长(>1 mil行),运行这些查询所需的时间非常长,每个查询大约需要20分钟。寻找关于如何改进这些查询以减少运行时间的输入。谢谢

好问题 面临的挑战是通过迭代将每一行分组并跳转 因此,我们需要定义一个开始期间和结束期间,并在这些期间之间连接同一个表

由于表的大小,我添加了orderby和limit

我还将向rownum列添加索引,以使联接和组运行得更快

希望有帮助

ALTER TABLE temp_data ADD key rownum (rownum) ;


    SELECT 
         t3.rownum AS endp, 
        AVG(t3.last_price)
        FROM
temp_data t3
INNER JOIN temp_data t ON t.rownum BETWEEN  MAX(IFNULL(t3.rownum, 0)) - 50 AND t3.endp
        GROUP BY
        endp
ORDER BY rownum DESC
LIMIT 0,1000

好的。首先,由于只有1百万行,这不需要20分钟。大概20秒。如果rownum列是唯一的,则应将其作为唯一键进行索引。它还应该是一个未签名的int。执行这些操作将大大缩短查询时间,因为现在您似乎正在对每个连接执行完整的未排序表扫描

其次,除非有某种原因对于比较大量历史数据的数据库来说并不明显,否则您应该使用ISAM表,而不是InnoDB

第三,必须为脚本代码编制索引,否则将进行全表扫描

更多:
*方法2中的join语句将每一行连接到每一行,然后执行where。您应该在rownum>t1.rownum-50上留下JOIN,而rownum这看起来很像Oracle代码。你确定你在使用MySQL吗?是的,我确定…在MySQL服务器中使用它们,MySQL服务器也托管在我的机器上。请发布一些表结构和示例数据。似乎
rownum
实际上是一个列名。我添加了表结构。rownum是具有连续行号的列。ID是主键,但不是连续的,所以我必须添加一个单独的列。不确定如何为数据添加示例附件。我如何将其附加到这里?您没有索引。最重要的是,这是影响性能的因素。您确定这会更快吗?我需要放松子查询并添加适当的限制。。。我还想扩展我关于indexesIt的回答。如果去掉多余的rownum列也很好坦白地说,将整个内容复制到一个以rownum为主键的新表中会比这快得多,但最糟糕的是初始查询中的无限连接。。。如果将日期编入索引,这应该会更快,但它可能会通过将数据分块到日期段来创建工件或不一致。这非常有效。明白你的意思了,只加入数据集的一部分。这大大减少了运行时间。谢谢十年前,关于MyISAM vs InnoDB的旧观点可能有一些道理,但现在不再是了。此外,引用完整性胜过任何(微小的,我怀疑,根本不存在的)潜在性能好处完全公开,十年前我用InnoDB做过几乎所有的事情。事实上,很多关于大型表上的锁会使大型数据库崩溃的情况让我确信,使用完全简短的写锁和MyISAM比使用行级锁更好。经过这么多年,我的直觉是MyISAM的大连接速度更快,但这同样来自于一个几乎总是有一些写入尝试同时发生的环境,因此只读环境中的速度差异可能可以忽略不计。问题是,如果你不需要它,为什么要用它?
  CREATE TABLE `temp_data` (
  `id` int(11) NOT NULL DEFAULT '0',
  `rownum` int(11) DEFAULT NULL,
  `script_code` float DEFAULT NULL,
  `date` date DEFAULT NULL,
  `time` time DEFAULT NULL,
  `last_price` float DEFAULT NULL,
  `last_qty` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE temp_data ADD key rownum (rownum) ;


    SELECT 
         t3.rownum AS endp, 
        AVG(t3.last_price)
        FROM
temp_data t3
INNER JOIN temp_data t ON t.rownum BETWEEN  MAX(IFNULL(t3.rownum, 0)) - 50 AND t3.endp
        GROUP BY
        endp
ORDER BY rownum DESC
LIMIT 0,1000