Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Opération mathématiques dans les select

6 réponses
Avatar
Lionel
Bonjour,

J'ai une table contenant des valeurs numériques a, b et c, d.
Je vais devoir faire des calculs de type:
somme (a-b)
somme((a-b)/d)
somme ((a-c)/d)
somme (a/c)
somme (b/c)
....
Je connais tous les types de calcul possibles (une dizaine)

La table va contenir plusieurs millions de lignes.
J'hésite entre 2 options:
- Pré-calculer toutes les opérations possibles et stocker les résultats lors
de l'insert
- faire les calculs dans les select

La solution 1 me semble évidemment plus performante, mais m'oblige à ajouter
une dizaine de colonnes pas forcément indispensables.
D'après vous, quelle sera la perte de perf en utilisant l'option 2 ?

base: PostreSql 8.1

Merci pour vos retours d'expérience.

6 réponses

Avatar
Bruno Baguette
Lionel a écrit :

La table va contenir plusieurs millions de lignes.
J'hésite entre 2 options:
- Pré-calculer toutes les opérations possibles et stocker les résultats lors
de l'insert
- faire les calculs dans les select

La solution 1 me semble évidemment plus performante, mais m'oblige à ajouter
une dizaine de colonnes pas forcément indispensables.
D'après vous, quelle sera la perte de perf en utilisant l'option 2 ?

base: PostreSql 8.1



Bonjour !

Il manque une donnée dans votre énoncé : vous ne précisez pas si cette
table sera très fréquemment utilisée ou non.

Si cette table n'est pas utilisée de manière très intensive, je ferais
les calculs lors des select.

En revanche, si cette table est fort utilisée, je mettrais un trigger
sur les colonnes a, b, c, et d, qui se chargerait de mettre à jour les
colonnes contenant vos résultats de calculs lors de chaque mise à jour
de a,b,c et d, et lors de chaque ajout de nouveaux enregistrements.

N'oubliez pas vos index sur cette table, les performances en dépendent
grandement ! :-)

--
Bruno Baguette -
Avatar
Lionel
Bruno Baguette wrote:
Il manque une donnée dans votre énoncé : vous ne précisez pas si cette
table sera très fréquemment utilisée ou non.



Effectivement, j'ai oublié 2 détails qui ont leur importance:
1) les données ne seront jamais modifiées, uniquement insérées par lot de
plusieurs centaines de lignes, d'ou l'idée de précalculer les valeurs lors
de l'insertion.
2) il s'agit d'un appli web, donc je ne peux pas trop prévoir la façon dont
les utilisateurs vont s'en servir.
Logiquement, vu qu'il y a pas mal de temps pour analyser les données, je
dirais maxi 5 requetes en vrai simultané.
Mais sur du web, chaque seconde compte à l'affichage, et moins le serveur
est chargé, mieux il se porte (il héberge d'autres appli).

N'oubliez pas vos index sur cette table, les performances en dépendent
grandement ! :-)



ça je n'oublie jamais :)

Bon, je suis parti pour tester les deux cas, passer d'une valeur calculée à
la volée à une valeur précalculée ne devrait prendre que quelques minutes de
toutes façons, on verra bien ce que ca donne.
Avatar
nobody
Lionel a écrit :
Bonjour,

J'ai une table contenant des valeurs numériques a, b et c, d.
Je vais devoir faire des calculs de type:
somme (a-b)
somme((a-b)/d)
somme ((a-c)/d)
somme (a/c)
somme (b/c)
....
Je connais tous les types de calcul possibles (une dizaine)

La table va contenir plusieurs millions de lignes.
J'hésite entre 2 options:
- Pré-calculer toutes les opérations possibles et stocker les résultats lors
de l'insert
- faire les calculs dans les select

La solution 1 me semble évidemment plus performante, mais m'oblige à ajouter
une dizaine de colonnes pas forcément indispensables.
D'après vous, quelle sera la perte de perf en utilisant l'option 2 ?

base: PostreSql 8.1

Merci pour vos retours d'expérience.




la solution 1 n'est pas forcement la plus performante car cela augmente
fortement la taille de la table donc le nombre d'accès disque qui sont
très lent

tandis que le calcul fait travaille le processeur qui est lui très rapide

donc il se peut très bien que calculer soit plus rapide que de lire les
valeurs sur disque
Avatar
Gilles TOURREAU
Le Tue, 03 Jul 2007 10:26:51 +0200, Lionel <SPAMcoollATfreePOINTfr> a
écrit:

Bruno Baguette wrote:
Il manque une donnée dans votre énoncé : vous ne précisez pas si cette
table sera très fréquemment utilisée ou non.



Effectivement, j'ai oublié 2 détails qui ont leur importance:
1) les données ne seront jamais modifiées, uniquement insérées par lot de
plusieurs centaines de lignes, d'ou l'idée de précalculer les valeurs
lors
de l'insertion.
2) il s'agit d'un appli web, donc je ne peux pas trop prévoir la façon
dont
les utilisateurs vont s'en servir.
Logiquement, vu qu'il y a pas mal de temps pour analyser les données, je
dirais maxi 5 requetes en vrai simultané.
Mais sur du web, chaque seconde compte à l'affichage, et moins le serveur
est chargé, mieux il se porte (il héberge d'autres appli).

N'oubliez pas vos index sur cette table, les performances en dépendent
grandement ! :-)



ça je n'oublie jamais :)

Bon, je suis parti pour tester les deux cas, passer d'une valeur
calculée à
la volée à une valeur précalculée ne devrait prendre que quelques
minutes de
toutes façons, on verra bien ce que ca donne.





Est-ce que dans vos SELECT vous devez utiliser ces champs dans la clause
WHERE ? Si c'est non, combien de lignes sont renvoyées en moyenne par
requête ?

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Avatar
Lionel
Gilles TOURREAU wrote:
Est-ce que dans vos SELECT vous devez utiliser ces champs dans la
clause WHERE ? Si c'est non, combien de lignes sont renvoyées en
moyenne par requête ?



Non, ils ne sont jamais utilisés dans le where.
Les requetes seront du style:
select group1, group2, group3, somme(formule1), somme (formule2), ... somme
(formuleX)
where cond1 and cond2
group by group1, group2, group3
X étant compris entre 3 et 10.
Les conditions concernent les groupes et d'autres tables liées
Les formules peuvent etre de type a/b ou (a-b)/c
Les requetes devraient remonter entre 300 et 2000 lignes, avec une moyenne
se situant dans les 700.
Avatar
Lionel
nobody wrote:
la solution 1 n'est pas forcement la plus performante car cela
augmente fortement la taille de la table donc le nombre d'accès
disque qui sont très lent



Finalement, il me semble que le top est de stocker uniquement a, b, c, d et
faire les calculs dans l'appli et non pas dans la requete sql.
Avantages:
- moins de colonnes chargées en mémoire par les select (uniquement
somme(a),somme(b),somme(c),somme(d))
- peu de colonnes à stocker sur le disque
- code évolutif sans restructurer la base ni modifier les requetes SQL

Merci pour les infos !