Mysql 插入/更新SMA的查询速度(简单移动平均)
我想在我的表中包含一列股票数据的简单移动平均值。我已经成功地创建了几个查询,但是查询速度很慢。我的目标是提高查询速度 我有下表:Mysql 插入/更新SMA的查询速度(简单移动平均),mysql,sql,date,sql-update,query-optimization,Mysql,Sql,Date,Sql Update,Query Optimization,我想在我的表中包含一列股票数据的简单移动平均值。我已经成功地创建了几个查询,但是查询速度很慢。我的目标是提高查询速度 我有下表: CREATE TABLE `timeseries_test` ( `timeseries_id` int(11) NOT NULL AUTO_INCREMENT, `stock_id` int(10) NOT NULL, `date` date NOT NULL, `open` decimal(16,8) NOT NULL, `high` decimal(1
CREATE TABLE `timeseries_test` (
`timeseries_id` int(11) NOT NULL AUTO_INCREMENT,
`stock_id` int(10) NOT NULL,
`date` date NOT NULL,
`open` decimal(16,8) NOT NULL,
`high` decimal(16,8) NOT NULL,
`low` decimal(16,8) NOT NULL,
`close` decimal(16,8) NOT NULL,
`adjusted_close` double(16,8) NOT NULL,
`volume` int(16) NOT NULL,
`dividend` double(16,8) NOT NULL,
`split_coefficient` double(16,15) NOT NULL,
`100sma` decimal(16,8) NOT NULL,
PRIMARY KEY (`timeseries_id`),
KEY `stock` (`stock_id`),
KEY `date` (`date`),
KEY `date_stock` (`stock_id`,`date`)
) ENGINE=InnoDB AUTO_INCREMENT=5444325 DEFAULT CHARSET=latin1
我尝试过许多不同的查询格式,但每5000行都需要25秒。select查询只需不到一秒钟的时间。下面是一个查询示例:
UPDATE stock.timeseries_test t1 INNER JOIN (
SELECT a.timeseries_id,
Round( ( SELECT SUM(b.close) / COUNT(b.close)
FROM timeseries_test AS b
WHERE DATEDIFF(a.date, b.date) BETWEEN 0 AND 99 AND a.stock_id = b.stock_id
), 2 ) AS '100sma'
FROM timeseries_test AS a) t2
ON t1.`timeseries_id` = t2.`timeseries_id`
SET t1.100sma = t2.100SMA
WHERE t2.100sma = null
在解释查询下面:
1 PRIMARY <derived2> NULL ALL NULL NULL NULL NULL 10385 10.00 Using where
1 UPDATE t1 NULL eq_ref PRIMARY PRIMARY 4 t2.timeseries_id 1 100.00 NULL
2 DERIVED a NULL index NULL date_stock 7 NULL 10385 100.00 Using index
3 DEPENDENT SUBQUERY b NULL ref stock,date_stock stock 4 stock.a.stock_id 5192 100.00 Using where
1主NULL所有NULL 10385 10.00使用where
1更新t1 NULL eq_ref PRIMARY 4 t2.timeseries_id 1 100.00 NULL
2使用索引导出空索引空日期\u股票7空10385 100.00
3依赖子查询b NULL ref stock,date_stock 4 stock.a.stock_id 5192 100.00使用where
感谢您的帮助 如果您运行的是MySQL 8.0,我建议窗口函数使用
范围
规范;这就是对相关子查询的需要
update stock.timeseries_test t1
inner join (
select timeseries_id,
avg(close) over(
partition by stock_id
order by date
range between interval 99 day preceding and current row
) `100sma`
from timeseries_test
) t2 on t1.timeseries_id = t2.timeseries_id
set t1.`100sma` = t2.`100sma`
不清楚原始的外部where
子句的目的是什么,所以我删除了它:
WHERE t2.`100sma` = null
如果确实要检查null
ness,则需要为null
;但这样做几乎会破坏update
语句的整个逻辑。也许你的意思是:
WHERE t1.`100sma` is null
函数是不可搜索的。而不是
DATEDIFF(a.date, b.date) BETWEEN 0 AND 99
使用
(或者应该交换a
和b
)
我怀疑(从列名来看)这对(stock\u id
,date
)是唯一的,timeseries\u id
从未真正使用过。如果这些是正确的,那么
PRIMARY KEY (`timeseries_id`),
KEY `date_stock` (`stock_id`,`date`)
-->
需要将ON(timestamp_id)上的更改为测试这两列
另外,由于还有另一个索引以相同的列开头,所以请忽略此项:
感谢您的反馈。不过,我正在运行MySQL 5.7.2。如果我没有找到替代解决方案,我会尝试。
PRIMARY KEY (`timeseries_id`),
KEY `date_stock` (`stock_id`,`date`)
PRIMARY KEY(`stock_id`,`date`)
KEY `stock` (`stock_id`),