J'ai une requête qui ajoute plusieurs valeurs de colonne dans la clause WHERE
. Je ne peux pas précalculer cet ajout dans une seule colonne car la combinaison de colonnes à utiliser varie d'une requête à l'autre. Mon problème est que ma table est très grande (plusieurs centaines de millions de lignes) et les performances très mauvaises.Performances MySQL de la requête ajoutant des colonnes dans la clause where
table Exemple:
+---------+------------+--------+--------+--------+--------+
| tableId | categoryId | value1 | value2 | value3 | value4 |
+---------+------------+--------+--------+--------+--------+
| 1 | 1 | 1 | 0 | 5 | 7 |
| 2 | 1 | 8 | 1 | 7 | 0 |
| 3 | 1 | 10 | 5 | 0 | 20 |
| 4 | 2 | 0 | 15 | 0 | 22 |
| 5 | 2 | 20 | 0 | 11 | 0 |
+---------+------------+--------+--------+--------+--------+
Exemple requêtes:
SELECT * FROM myTable WHERE categoryId = 1 AND (value1 + value2 + value3 + value4) > 9;
SELECT * FROM myTable WHERE categoryId = 1 AND (value1 + value3 + value4) > 5;
Quelle serait la meilleure stratégie pour améliorer les performances de ces questions? (edit: J'ai déjà un index sur categoryId
, cela n'aide pas)
L'utilisation d'un index aide-t-elle pour de telles requêtes? Devrais-je alors créer tous les index possibles pour toutes les combinaisons possibles de colonnes? Les index obtenus ne seraient-ils pas très très grands? Ou peut-être créer une table de liens, avec des champs de valeur booléenne spécifiant quelles colonnes ont été utilisées? Mais cela se traduirait par une table avec plusieurs milliards de lignes, pas sûr que ce soit mieux ...
+---------+-----------+-----------+-----------+-----------+----------+
| tableId | useValue1 | useValue2 | useValue3 | useValue4 | valueSum |
+---------+-----------+-----------+-----------+-----------+----------+
| 1 | 1 | 1 | 1 | 1 | 13 |
| 1 | 1 | 1 | 1 | 0 | 6 |
| 1 | 1 | 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 0 | 1 | 8 |
| 1 | 1 | 0 | 1 | 1 | 13 |
| 1 | 1 | 0 | 1 | 0 | 6 |
| 1 | 1 | 0 | 0 | 0 | 1 |
| 1 | 1 | 0 | 0 | 1 | 8 |
| 1 | 0 | 1 | 1 | 1 | 12 |
| 1 | 0 | 1 | 1 | 0 | 5 |
| 1 | 0 | 1 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 | 1 | 7 |
| 1 | 0 | 0 | 1 | 1 | 12 |
| 1 | 0 | 0 | 1 | 0 | 5 |
| 1 | 0 | 0 | 0 | 1 | 7 |
+---------+-----------+-----------+-----------+-----------+----------+
Avec un Indice
ALTER TABLE linkTable INDEX(tableId, useValue1, useValue2, useValue3, useValue4, valueSum);
D'autres idées?
Comment peut-on comprendre cela sans que vos données soient en réalité !!!! – e4c5
@ e4c5: Je suis d'accord et je pourrais faire un autre post questionnant l'ensemble du flux de travail, les calculs, les sorties et le stockage. Mais c'est à quoi je dois faire face aujourd'hui :) Que penses-tu de ma deuxième idée? – FBB
Les colonnes énumérées sont symptomatiques d'une mauvaise conception, ce qui peut affecter les performances. – Strawberry