Bonjour à tous,
Je ne suis pas développeur de formation mais je travaille avec une base MySQL qui commence à être assez massive. Parmi les grosses tables, meter_table_fr compte plus de 10 million de lignes. Elle contient les données de production d'une trentaine de compteurs d'énergie et ce depuis quelques années déjà. Les champs 'compteur' et 'plant_id' représente schématiquement les compteurs à quelques nuances près.
J'ai deux index sur 'compteur' et 'plant_id' et partionner sur YEAR(date).
Voici à quoi ressemble la table.
Les requêtes suivantes répondent en plus ou moins 50-60 secondes.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 CREATE TABLE `meter_data_fr_copy` ( `id` int(11) NOT NULL AUTO_INCREMENT, `plant_id` int(11) NOT NULL, `trigram` char(5) DEFAULT NULL, `compteur` char(5) DEFAULT NULL, `tstamp` datetime NOT NULL, `is_erdf` tinyint(4) NOT NULL COMMENT 'set to 1 if erdf data 0 if actaris data', `power` smallint(6) DEFAULT NULL, `data_ok` int(11) DEFAULT NULL, `comment` varchar(100) DEFAULT NULL, `mail_download_log_id_ref` int(11) DEFAULT NULL, `avail` decimal(11,2) DEFAULT '1.00', PRIMARY KEY (`id`,`plant_id`,`tstamp`), KEY `idx_pid` (`plant_id`) USING BTREE, KEY `idx_compteur` (`compteur`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=35497903 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (YEAR(tstamp)) (PARTITION p2013 VALUES LESS THAN (2013) ENGINE = InnoDB, PARTITION p2014 VALUES LESS THAN (2014) ENGINE = InnoDB, PARTITION p2015 VALUES LESS THAN (2015) ENGINE = InnoDB, PARTITION p2016 VALUES LESS THAN (2016) ENGINE = InnoDB, PARTITION p2017 VALUES LESS THAN (2017) ENGINE = InnoDB, PARTITION p2018 VALUES LESS THAN (2018) ENGINE = InnoDB, PARTITION p2019 VALUES LESS THAN (2019) ENGINE = InnoDB, PARTITION p2020 VALUES LESS THAN (2020) ENGINE = InnoDB, PARTITION p2021 VALUES LESS THAN (2021) ENGINE = InnoDB, PARTITION p2022 VALUES LESS THAN (2022) ENGINE = InnoDB, PARTITION p2023 VALUES LESS THAN (2023) ENGINE = InnoDB) */;
ou
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 SELECT plant_id, SUM(power) FROM meter_data_fr WHERE tstamp BETWEEN "2018-01-01" and "2018-02-01" GROUP BY plant_id
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 SELECT compteur, SUM(power) FROM meter_data_fr WHERE year(tstamp) = 2018 and tstamp BETWEEN "2018-01-01" and "2018-02-01" GROUP BY compteur
J'aimerais vraiment que ça tourne en 10 fois moins de temps. La seule piste que j'ai pour le moment est de scinder la table en une "archive" pour les années passées et une table "courante" pour l'année en cours. C'est un peu pénible pour la maintenance.
Avez-vous une meilleur idée, des suggestions, des conseils pour optimiser cette table et/ou les requêtes?
Merci d'avance pour vos réponses éclairées
Partager