Opération mathématiques dans les select

Le
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.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Bruno Baguette
Le #21852221
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 -
Lionel
Le #21852211
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.
nobody
Le #21852201
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
Gilles TOURREAU
Le #21852191
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
Lionel
Le #21852181
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.
Lionel
Le #21852171
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 !
Publicité
Poster une réponse
Anonyme