[英]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.