繁体   English   中英

mysql中的多个移动平均线

[英]multiple moving averages in mysql

我必须在 mysql 中计算我的数据集的移动平均线(不同时期)。 我尝试了 2 种方法来计算平均值,但都需要花费大量时间。 分享下面的代码。

方法:-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;

方法:-2

select t1.*, avg(t2.last_price) 'ma_small_price'
from temp_data t1
join temp_data t2
where t2.rownum>t1.rownum-50 and t2.rownum<=t1.rownum and t1.script_code=t2.script_code
group by t1.id,t1.date, t1.time;

这是表结构:

  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;

rownum 是具有连续行号的列。 ID 是主键但不是连续的,所以我不得不添加一个单独的列

示例数据链接: https : //www.dropbox.com/s/z8iacqvlkjdx6ax/temp_data_sample.xlsx?dl=0

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

我的数据集巨大且不断增长(> 100 万行),运行这些查询所需的时间很长 - 每个约 20 分钟。 寻求有关如何改进这些查询以减少运行时间的输入。 谢谢!!

好问题 挑战是按迭代对每一行进行分组 所以我们需要定义一个开始时间段和一个结束时间段,并在这些时间段之间加入同一个表

由于表的大小,我添加了 order by 和 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

好的。 首先,只有 100 万行,这不应该需要 20 分钟。 更像是20秒。 如果您的 rownum 列是唯一的,则应将其索引为唯一键。 它也应该是一个无符号整数。 做这些事情会大大减少您的查询时间,因为现在您似乎正在对每个连接进行完整的未排序表扫描。

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

第三,必须对 script_code 进行索引,否则您将进行全表扫描。

更多: * 您在方法 2 中的 join 语句将每一行连接到每一行,然后执行 where。 您应该 LEFT JOIN ON rownum>t1.rownum-50 AND rownum<=t1.rownum,而不是进行一般连接然后运行 ​​where。 即使没有索引rownum,这也会显着加快查询速度。 * 如果您希望获得更多数据,您还应该考虑根据 rownum 对表进行分区。 分区非常适合加速这类读取,其中您访问的大部分数据都是连续的,并且会落在一两个分区内。 在您的情况下,您还可以按日期分区,这对于其他操作可能很方便。 * 查看 EXPLAIN SELECT 并查看连接上使用了哪些键。 考虑一个 USE INDEX 提示来使用 rownum 而不是连接的主键。

您的任何一个查询本身似乎都不正确。 一旦您完成了上述优化,我的猜测是您的方法 1(子查询)仍然比没有方法 2 中的 WHERE 的正确 JOIN ON 更快。

此时,您应该使用 EXPLAIN SELECT 来查看每个查询中正在执行的操作。 它将显示有多少行被读取和连接,以及正在使用哪些索引,帮助您缩小未索引连接的任何问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM