I am trying to optimize a MySQL query. I am trying to update the column of a table with a moving average of the price of an item every 15 minutes for a specific store.
My table has the following structure
╔═════╦═════════════════════╦════════════╦══════╦════════════════╗
║ ID ║ DATETIME ║ NAME ║Price ║ 15_MIN_AVERAGE ║
╠═════╬═════════════════════╬════════════╬══════╬════════════════╣
║ 1 ║ 2000-01-01 00:00:05 ║ WALMART ║ 1 ║ ║
║ 2 ║ 2000-01-01 00:00:05 ║ BESTBUY ║ 6 ║ ║
║ 3 ║ 2000-01-01 00:00:05 ║ RADIOSHACK ║ 2 ║ ║
║ 4 ║ 2000-01-01 00:00:10 ║ WALMART ║ 6 ║ ║
║ 5 ║ 2000-01-01 00:00:10 ║ BESTBUY ║ 2 ║ ║
║ 6 ║ 2000-01-01 00:00:10 ║ RADIOSHACK ║ 8 ║ ║
║ 7 ║ 2000-01-01 00:00:15 ║ WALMART ║ 10 ║ ║
║ 8 ║ 2000-01-01 00:00:15 ║ BESTBUY ║ 2 ║ ║
║ 9 ║ 2000-01-01 00:00:15 ║ RADIOSHACK ║ 3 ║ ║
║ 10 ║ 2000-01-01 00:00:20 ║ WALMART ║ 6 ║ ║
║ 11 ║ 2000-01-01 00:00:20 ║ BESTBUY ║ 4 ║ ║
║ 12 ║ 2000-01-01 00:00:20 ║ RADIOSHACK ║ 5 ║ ║
║ 13 ║ 2000-01-01 00:00:25 ║ WALMART ║ 1 ║ ║
║ 14 ║ 2000-01-01 00:00:25 ║ BESTBUY ║ 0 ║ ║
║ 15 ║ 2000-01-01 00:00:25 ║ RADIOSHACK ║ 5 ║ ║
║ 16 ║ 2000-01-01 00:00:30 ║ WALMART ║ 1 ║ ║
║ 17 ║ 2000-01-01 00:00:30 ║ BESTBUY ║ 6 ║ ║
║ 18 ║ 2000-01-01 00:00:30 ║ RADIOSHACK ║ 2 ║ ║
║ 19 ║ 2000-01-01 00:00:35 ║ WALMART ║ 6 ║ ║
║ 20 ║ 2000-01-01 00:00:35 ║ BESTBUY ║ 2 ║ ║
║ 21 ║ 2000-01-01 00:00:35 ║ RADIOSHACK ║ 8 ║ ║
║ 22 ║ 2000-01-01 00:00:40 ║ WALMART ║ 10 ║ ║
║ 23 ║ 2000-01-01 00:00:40 ║ BESTBUY ║ 2 ║ ║
║ 24 ║ 2000-01-01 00:00:40 ║ RADIOSHACK ║ 3 ║ ║
║ 25 ║ 2000-01-01 00:00:45 ║ WALMART ║ 6 ║ ║
║ 26 ║ 2000-01-01 00:00:45 ║ BESTBUY ║ 4 ║ ║
║ 27 ║ 2000-01-01 00:00:45 ║ RADIOSHACK ║ 5 ║ ║
║ 28 ║ 2000-01-01 00:00:48 ║ WALMART ║ 1 ║ ║
║ 29 ║ 2000-01-01 00:00:48 ║ BESTBUY ║ 0 ║ ║
║ 30 ║ 2000-01-01 00:00:48 ║ RADIOSHACK ║ 5 ║ ║
║ 31 ║ 2000-01-01 00:00:50 ║ WALMART ║ 6 ║ ║
║ 32 ║ 2000-01-01 00:00:50 ║ BESTBUY ║ 4 ║ ║
║ 33 ║ 2000-01-01 00:00:50 ║ RADIOSHACK ║ 5 ║ ║
║ 34 ║ 2000-01-01 00:00:55 ║ WALMART ║ 1 ║ ║
║ 35 ║ 2000-01-01 00:00:55 ║ BESTBUY ║ 0 ║ ║
║ 36 ║ 2000-01-01 00:00:55 ║ RADIOSHACK ║ 5 ║ ║
║ 37 ║ 2000-01-01 00:01:00 ║ WALMART ║ 1 ║ ║
║ 38 ║ 2000-01-01 00:01:00 ║ BESTBUY ║ 0 ║ ║
║ 39 ║ 2000-01-01 00:01:00 ║ RADIOSHACK ║ 5 ║ ║
╚═════╩═════════════════════╩════════════╩══════╩════════════════╝
My query is:
UPDATE my_table AS t
INNER JOIN
( select ID,
(select avg(price) from my_table as t2
where
t2.datetime between subtime(t1.datetime, '00:14:59') and t1.datetime AND
t2.name = t1.name
) as average
from my_table as t1
where
minute(datetime) in (0,15,30,45) ) as sel
ON t.ID = sel.ID
SET 15_MIN_AVERAGE = average
I have an index on column DATETIME (which is of type DATETIME), but I think using a function such as minute() and subtime() in a where clause basically nullifies the index.
My table has around 1.6 million records (about one record every 5 minutes). Currently, it takes a very long time to run this query (over an hour), which is unacceptable.
What do you recommend to optimize it?
Thank you very much!