Naar aanleiding van het oude topic van mij (MySQL totaal berekenen over tijdspanne van 1 uur, mei 2013) open ik nu een nieuw topic. De query werkt namelijk, alleen de performance is bedroevend.
Het opwekken van energie via zonnepanelen wordt gelogd in de database. Ruwweg elke 10 minuten wordt er de totale opwekking van een locatie (sinds het plaatsen van de omvormer, dus cumulatief) en nog een paar waardes weggeschreven.
Nu wil ik graag via MySQL bepalen hoeveel er totaal, per uur, opgewekt wordt door alle locaties bij elkaar.
Als voorbeeld gebruik ik de volgende dataset:
En met de volgende query
Krijg ik netjes de volgende output.
(zie ook het voorbeeld op sqlfiddle)
het klopt dat het 1e uur van de dag nu nog op 0/null komt te staan, dat is voorlopig een kleine bug die ik accepteer.
Bij een kleine dataset gaat dat prima. Echter bij de volledige dataset van ruim 1 miljoen records neemt deze query zo 3 - 5 minuten in beslag. De volledige set bestaat uit nog 4 kolommen meer, maar deze worden niet geselecteerd dus dat lijkt me niet het probleem.
Kortom, hoe kan ik deze query optimaliseren dan wel herschrijven? De huidige performance is bedroevend en ik ben nu bijna geneigd om via PHP i.c.m. foreach handmatig elk uur te gaan berekenen.
Aangezien er ongeveer elke minuut wel weer nieuwe waardes gepost worden heeft query caching ook geen nut.
Wie o wie kan me (in de goede richting) helpen?!
Het opwekken van energie via zonnepanelen wordt gelogd in de database. Ruwweg elke 10 minuten wordt er de totale opwekking van een locatie (sinds het plaatsen van de omvormer, dus cumulatief) en nog een paar waardes weggeschreven.
Nu wil ik graag via MySQL bepalen hoeveel er totaal, per uur, opgewekt wordt door alle locaties bij elkaar.
Als voorbeeld gebruik ik de volgende dataset:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| | ID | ID_LOCATIE | TIME | ENERGY_TOTAL | |----|------------|-------------------------------|--------------| | 1 | 1 | August, 04 2014 07:08:00+0000 | 500 | | 2 | 2 | August, 04 2014 07:09:00+0000 | 1000 | | 3 | 1 | August, 04 2014 07:58:00+0000 | 1000 | | 4 | 2 | August, 04 2014 07:54:00+0000 | 1200 | | 5 | 1 | August, 04 2014 08:04:00+0000 | 1300 | | 6 | 2 | August, 04 2014 08:06:00+0000 | 1600 | | 7 | 1 | August, 04 2014 08:56:00+0000 | 1500 | | 8 | 2 | August, 04 2014 08:59:00+0000 | 1700 | | 9 | 1 | August, 04 2014 09:01:00+0000 | 1750 | | 10 | 2 | August, 04 2014 09:02:00+0000 | 1900 | | 11 | 1 | August, 04 2014 09:57:00+0000 | 2100 | | 12 | 2 | August, 04 2014 09:58:00+0000 | 2400 | | 13 | 1 | August, 04 2014 10:08:00+0000 | 2500 | | 14 | 2 | August, 04 2014 10:04:00+0000 | 2700 | | 15 | 1 | August, 04 2014 10:56:00+0000 | 3000 | | 16 | 2 | August, 04 2014 10:57:00+0000 | 3250 | |
En met de volgende query
MySQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| select hour(time), SUM(hourly_energy) as e FROM ( select time, id_locatie, round(max(energy_total)) - ( select round(max(energy_total)) from data_running_summed s2 where date(time) = date('2014-08-04') and hour(s2.time) = hour(s1.time)-1 and s2.id_locatie = s1.id_locatie group by hour(time) ) as hourly_energy from data_running_summed s1 where date(time) = date('2014-08-04') group by s1.id_locatie, hour(time) order by time ) as totalen GROUP BY hour(time) |
Krijg ik netjes de volgende output.
code:
1
2
3
4
5
6
| | HOUR(TIME) | E | |------------|--------| | 7 | (null) | | 8 | 1000 | | 9 | 1300 | | 10 | 1750 | |
(zie ook het voorbeeld op sqlfiddle)
het klopt dat het 1e uur van de dag nu nog op 0/null komt te staan, dat is voorlopig een kleine bug die ik accepteer.
Bij een kleine dataset gaat dat prima. Echter bij de volledige dataset van ruim 1 miljoen records neemt deze query zo 3 - 5 minuten in beslag. De volledige set bestaat uit nog 4 kolommen meer, maar deze worden niet geselecteerd dus dat lijkt me niet het probleem.
Kortom, hoe kan ik deze query optimaliseren dan wel herschrijven? De huidige performance is bedroevend en ik ben nu bijna geneigd om via PHP i.c.m. foreach handmatig elk uur te gaan berekenen.
Aangezien er ongeveer elke minuut wel weer nieuwe waardes gepost worden heeft query caching ook geen nut.
Wie o wie kan me (in de goede richting) helpen?!