Hallo meute,
um die Aggregation genauer zu verstehen und zu visualisieren, habe ich von deinen sample.sql Daten
34 Zeilen "2020-09-09 12:00:42" - "2020-09-09 12:50:12" in eine leere samples Tabelle mit insert eingfügt.
Wie schon von Karlheinz beschrieben geht das ganz gut mit zerlegten SQL-commands.
Also die eigentliche Aggregation findet in der time2 spalte statt durch Runden der Uhrzeit auf 900 Sekunden
mit den beiden Funktionen SEC_TO_TIME und TIME_TO_SEC statt.
Damit man das besser sieht hab ich zusätzlich die original time-spalte vor die time2-spalte eingefügt.
Man sieht dass die Uhrzeit jeder time-spalte in der time2-spalte auf 15Min oder 900 Sekunden gerundet wurde.
MariaDB [p4]> select address, type, 'A' as aggregate, time,
-> CONCAT(DATE(time), ' ', SEC_TO_TIME((TIME_TO_SEC(time) DIV 900) * 900)) time2,
-> unix_timestamp(sysdate()) as inssp, unix_timestamp(sysdate()) as updsp,
-> value, text, samples
-> from samples;
+---------+------+-----------+---------------------+---------------------+------------+------------+-------+------+---------+
| address | type | aggregate | time | time2 | inssp | updsp | value | text | samples |
+---------+------+-----------+---------------------+---------------------+------------+------------+-------+------+---------+
| 4 | VA | A | 2020-09-09 12:50:12 | 2020-09-09 12:45:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:48:42 | 2020-09-09 12:45:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:47:12 | 2020-09-09 12:45:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:45:42 | 2020-09-09 12:45:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:44:12 | 2020-09-09 12:30:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:42:42 | 2020-09-09 12:30:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:41:12 | 2020-09-09 12:30:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:39:42 | 2020-09-09 12:30:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:38:12 | 2020-09-09 12:30:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:36:42 | 2020-09-09 12:30:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:35:12 | 2020-09-09 12:30:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:33:42 | 2020-09-09 12:30:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:32:12 | 2020-09-09 12:30:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:30:42 | 2020-09-09 12:30:00 | 1778023279 | 1778023279 | 18.50 | NULL | 1 |
...
+---------+------+-----------+---------------------+---------------------+------------+------------+-------+------+---------+
34 rows in set (0,001 sec)
Display More
Nun müssen noch die Blöcke mit der gleichen Uhrzeit in der time2 spalte mit
group by CONCAT(DATE(time), ' ', SEC_TO_TIME((TIME_TO_SEC(time) DIV 900) * 900)) in jeweils eine Aggregat-Zeile zusammgefasst werden.
MariaDB [p4]> select address, type, 'A' as aggregate, time,
-> CONCAT(DATE(time), ' ', SEC_TO_TIME((TIME_TO_SEC(time) DIV 900) * 900)) time,
-> unix_timestamp(sysdate()) as inssp, unix_timestamp(sysdate()) as updsp,
-> round(sum(value)/count(*), 2) as value, text, count(*) samples
-> from samples
-> where aggregate != 'A'
-> and time < "2020-09-10"
-> group by CONCAT(DATE(time), ' ', SEC_TO_TIME((TIME_TO_SEC(time) DIV 900) * 900));
+---------+------+-----------+---------------------+---------------------+------------+------------+-------+------+---------+
| address | type | aggregate | time | time | inssp | updsp | value | text | samples |
+---------+------+-----------+---------------------+---------------------+------------+------------+-------+------+---------+
| 4 | VA | A | 2020-09-09 12:14:12 | 2020-09-09 12:00:00 | 1778023380 | 1778023380 | 18.00 | NULL | 10 |
| 4 | VA | A | 2020-09-09 12:29:12 | 2020-09-09 12:15:00 | 1778023380 | 1778023380 | 18.00 | NULL | 10 |
| 4 | VA | A | 2020-09-09 12:44:12 | 2020-09-09 12:30:00 | 1778023380 | 1778023380 | 18.50 | NULL | 10 |
| 4 | VA | A | 2020-09-09 12:50:12 | 2020-09-09 12:45:00 | 1778023380 | 1778023380 | 18.50 | NULL | 4 |
+---------+------+-----------+---------------------+---------------------+------------+------------+-------+------+---------+
4 rows in set (0,002 sec)
Und jetzt noch das ganze mit replace in die Tabelle reinschreiben:
MariaDB [p4]> replace into samples
-> select address, type, 'A' as aggregate,
-> CONCAT(DATE(time), ' ', SEC_TO_TIME((TIME_TO_SEC(time) DIV 900) * 900)) time,
-> unix_timestamp(sysdate()) as inssp, unix_timestamp(sysdate()) as updsp,
-> round(sum(value)/count(*), 2) as value, text, count(*) samples
-> from samples
-> where aggregate != 'A'
-> and time < "2020-09-10"
-> group by CONCAT(DATE(time), ' ', SEC_TO_TIME((TIME_TO_SEC(time) DIV 900) * 900));
Query OK, 4 rows affected (0,009 sec)
Records: 4 Duplicates: 0 Warnings: 0
MariaDB [p4]> select * from samples;
+---------+------+-----------+---------------------+------------+------------+-------+------+---------+
| address | type | aggregate | time | inssp | updsp | value | text | samples |
+---------+------+-----------+---------------------+------------+------------+-------+------+---------+
| 4 | VA | S | 2020-09-09 12:50:12 | 1599648612 | 1599648612 | 18.50 | NULL | 1 |
| 4 | VA | S | 2020-09-09 12:48:42 | 1599648522 | 1599648522 | 18.50 | NULL | 1 |
...
| 4 | VA | S | 2020-09-09 12:02:12 | 1599645732 | 1599645732 | 18.00 | NULL | 1 |
| 4 | VA | S | 2020-09-09 12:00:42 | 1599645642 | 1599645642 | 18.00 | NULL | 1 |
| 4 | VA | A | 2020-09-09 12:45:00 | 1778023730 | 1778023730 | 18.50 | NULL | 4 |
| 4 | VA | A | 2020-09-09 12:30:00 | 1778023730 | 1778023730 | 18.50 | NULL | 10 |
| 4 | VA | A | 2020-09-09 12:15:00 | 1778023730 | 1778023730 | 18.00 | NULL | 10 |
| 4 | VA | A | 2020-09-09 12:00:00 | 1778023730 | 1778023730 | 18.00 | NULL | 10 |
+---------+------+-----------+---------------------+------------+------------+-------+------+---------+
38 rows in set (0,001 sec)
Display More
Was mir hierbei auffiel ist, dass die Originalzeilen erhalten blieben und die neuen Aggregat-Zeilen hinten angehängt wurden.
Das mit "replace" auch daten insertet werden können, wusste ich bisher auch nicht. Man lernt immer wieder dazu.
In den Unterlagen zur MariaDB ist bei "Einführung von REPLACE INTO" zu lesen.
Die REPLACE INTOAnweisung in MariaDB ermöglicht es, sowohl Einfügungen als auch Aktualisierungen mit einem einzigen SQL-Befehl durchzuführen.
Die grundlegende Syntax ähnelt der von `setup` INSERT INTO, jedoch mit einer Besonderheit:
Existiert bereits eine Zeile mit dem angegebenen Primärschlüssel oder eindeutigen Index, wird diese gelöscht und durch die neue Zeile ersetzt,
was von außen wie eine Aktualisierungsoperation aussieht.
Also die samples-Tabelle wird durch das Aggregieren zuerst mal grösser um die Anzahl der neuen Aggregat-Zeilen.
In diesem Beispiel steigt die Anzahl der Einträge von 34 auf 38 Zeilen in der samples-Tabelle.
Die anschliessende Bereinigung mit dem delete-statement von aggregate != 'A' räumt dann wieder auf.
MariaDB [p4]> delete from samples
-> where aggregate != 'A'
-> and time < "2020-09-10";
Query OK, 34 rows affected (0,009 sec)
In diesem Beispiel hat eine Aggregation die samples-Tabelle von 34 Zeilen auf 4 Zeilen, auf ca. ein zehntel reduziert.
Das bringt schon was und würde deine über 100 Millionen-record samples-Tabelle schon deutlich verkleinern und würde deine Space-Probleme beseitigen.
Das Aggregation-Bereinigung-script manuell aufgerufen mit den zwei Parametern Datum und Zeitintervall
funkioniert auch mit anderen Zeitintervallen als den 15 Minuten.
z.B ./aggregate-samples-manual.sh 2020-09-10 1800
MariaDB [p4]> select * from samples;
+---------+------+-----------+---------------------+------------+------------+-------+------+---------+
| address | type | aggregate | time | inssp | updsp | value | text | samples |
+---------+------+-----------+---------------------+------------+------------+-------+------+---------+
| 4 | VA | A | 2020-09-09 12:45:00 | 1778023065 | 1778023065 | 18.50 | NULL | 14 |
| 4 | VA | A | 2020-09-09 12:15:00 | 1778023065 | 1778023065 | 18.00 | NULL | 20 |
+---------+------+-----------+---------------------+------------+------------+-------+------+---------+
2 rows in set (0,001 sec)
Gruß
Jürgen

