Désolé pour mon manque de clarté, mais vous avez bien compris en ce qui concerne le type_info. Il s'agit bien du "nom" de l'une des 240 valeurs possible.
Par ailleurs, l'idée d'une table supplémentaire pour n'utiliser qu'un entier dans la clef primaire de APPAREIL_VALEUR me parfait effectivement plus intelligent.
Egalement, en faisant des test (merci EXPLAIN), je me suis rendu compte que la clef primaire suffisait. On se retrouve avec cette table:
1 2 3 4 5 6 7 8 9 10
| APPAREIL_VALEUR
(
AppareilId INT NOT NULL,
ValeurId INT NOT NULL,
ValeurDate TIMESTAMP NOT NULL;
ValeurString VARCHAR(32) NOT NULL,
ValeurWrite TINYINT(1) NOT NULL,
)
PRIMARY KEY (AppareilId, ValeurId, ValeurDate)
FOREIGN KEY (AppareilId) REFERENCES APPAREIL ; |
+----+------------+-----------+--------+----------------+---------+------------------------+-----+---------------------------------------+
| id | select_type| table | type | possible_keys | key | ref | rows| Extra |
+----+------------+-----------+--------+--------------- +---------+------------------------+-----+---------------------------------------+
| 1 | PRIMARY | <derived2>| ALL | NULL | NULL | NULL | 240 | Using temporary |
| 1 | PRIMARY | av | eq_ref | PRIMARY | PRIMARY | av_temp.AppareilId, ...| 1 | |
| 2 | DERIVED | av_bis | range | PRIMARY | PRIMARY | NULL | 1 | Using where; Using index for group-by |
+----+------------+-----------+--------+----------------+---------+------------------------+-----+---------------------------------------+
L'autre requête très sollicité est similaire, mais test que la boolean ValeurWrite, afin de ne récupérer que les valeurs "lues", et dont le système est sûr de la validité.
1 2 3 4 5 6 7 8 9 10 11
| SELECT av.AppareilId, av.ValeurDate, av.ValeurId, av.ValeurString, av.ValeurWrite
FROM APPAREIL_VALEUR AS av, (
SELECT MAX( ValeurDate) AS ValeurDate, AppareilId, ValeurId
FROM APPAREIL_VALEUR
WHERE AppareilId = ?
AND ValeurWrite IS FALSE
GROUP BY AppareilId, ValeurWrite, ValeurId
) AS av_temp
WHERE av.AppareilId = av_temp.AppareilId
AND av.ValeurId = av_temp.ValeurId
AND av.ValeurDate = av_temp.ValeurDate |
J'ai donc placer un index sur (AppareilId, ValeurWrite, ValeurId, ValeurDate)
Le résulat d'EXPLAIN dans ces conditions montre que MySQL utilise bien le nouvel index, mais le nombre de "rows" dépasse les 7000. J'imagine que l'on peut faire mieux... Mais je me vois mal essayer au hasard toutes les combinaisons d'index possible :p
+----+------------+-----------+--------+----------------------+-------------+------------------------+------+---------------------------------------+
| id | select_type| table | type | possible_keys | key | ref | rows | Extra |
+----+------------+-----------+--------+----------------------+-------------+------------------------+------+---------------------------------------+
| 1 | PRIMARY | <derived2>| ALL | NULL | NULL | NULL | 240 | Using temporary |
| 1 | PRIMARY | av | eq_ref | PRIMARY, idx_valeurs | PRIMARY | av_temp.AppareilId, ...| 1 | |
| 2 | DERIVED | av_bis | range | PRIMARY, idx_valeurs | idx_valeurs | NULL | 7297 | Using where; Using index for group-by |
+----+------------+-----------+--------+----------------------+-------------+------------------------+-----+---------------------------------------+
En tout cas, j'ai fais un grand pas en avant, merci à vous.
Partager