Précédent   Forum des professionnels en informatique > Bases de données > MySQL > SQL Procédural
SQL Procédural Forum d'entraide sur les triggers, les procédures stockées et les fonctions en MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 11/05/2004, 14h10   #1
Candidat au titre de Membre du Club
 
Inscription : mars 2004
Messages : 15
Détails du profil
Informations forums :
Inscription : mars 2004
Messages : 15
Points : 12
Points : 12
Par défaut Somme d'un element conditionnel

Bonjour,

Je cherche a calculer une somme en php-mysql. Actuellement la somme est effectuée dans le code php mais je me disais que ce serait surement plus rapide dans le code sql directement.

J'aimerais donner différents poid selon qu'un id se trouve dans tel ou tel group de valeur genre en pseudo code:
Code :
1
2
3
4
5
6
7
 
si id IN (80,90,199,101)
     SUM=SUM+1;
SINON SI id IN (30,1,2,34)
      SUM= SUM+0.8;
SINON SI id IN (31,32,9)
      SUM=SUM-5000000000;
J'aimerais ensuite pouvoir calculer la somme dans un GROUP BY enfonction de id_doc (la table a une condition d'unicité sur (id,id_doc) Je me suis donc dis qu'il serais plus simple de pouvoir faire un truc du genre :
Code :
1
2
 
SELECT sum(c) WHERE c=1 IF id IN (80,90,199,101) OR c=0.8 IF id IN((30,1,2,34).... GROUP BY id_doc
Une idée ?

PS: Il s'agit d'un serveur MySQL version 3.23
Synnalagma est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2004, 22h24   #2
Provisoirement toléré
 
Avatar de Maximilian
 
Inscription : juin 2003
Messages : 2 622
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 2 622
Points : 2 505
Points : 2 505
A mon avis il est beaucoup plus simple de gérer ce genre de choses dans du code PHP.
Enfin il y a toujours la fonction CASE ... WHEN (http://dev.mysql.com/doc/mysql/fr/Co...functions.html) mais je doute qu'on puisse l'utiliser dans un GROUP BY
__________________
Pensez au bouton
Maximilian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2004, 00h35   #3
Membre Expert
 
Avatar de Alexandre T
 
Inscription : mai 2002
Messages : 1 022
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France, Meurthe et Moselle (Lorraine)

Informations forums :
Inscription : mai 2002
Messages : 1 022
Points : 1 121
Points : 1 121
Exemple d'usage de la fonction CASE :
http://www.developpez.net/forums/viewtopic.php?t=192952
__________________
Alexandre T.

PHP5/MySQL5 Codes prêts à l'emploi
30 projets avec codes sources complets pour créer diaporamas photos, chat, arbre généalogique, statistiques de visites, création de graphiques, moteur de recherche, Sudoku etc...

Mes articles
Alexandre T est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2004, 02h53   #4
Nouveau Membre du Club
 
Inscription : avril 2004
Messages : 43
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 43
Points : 36
Points : 36
oui, je pense que tu devrais passer par les fonctions IF, CASE, IFNULL, etc.

un SUM(IF(...)) est possible, mais un SUM(CASE ...) : ... à tester

si tu peux arriver à gérer cela au niveau de la base plutôt qu'au niveau de l'appli, c'est le top.
toutes les opérations de regroupements, tris, calculs simples, etc. doivent être au maximum faites au niveau du SGBD : c'est fait pour ça et c'est plus rapide !
chicobra est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2004, 08h59   #5
Membre Expert
 
Avatar de Alexandre T
 
Inscription : mai 2002
Messages : 1 022
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France, Meurthe et Moselle (Lorraine)

Informations forums :
Inscription : mai 2002
Messages : 1 022
Points : 1 121
Points : 1 121
Citation:
Envoyé par chicobra
oui, je pense que tu devrais passer par les fonctions IF, CASE, IFNULL, etc.

un SUM(IF(...)) est possible, mais un SUM(CASE ...) : ... à tester

si tu peux arriver à gérer cela au niveau de la base plutôt qu'au niveau de l'appli, c'est le top.
toutes les opérations de regroupements, tris, calculs simples, etc. doivent être au maximum faites au niveau du SGBD : c'est fait pour ça et c'est plus rapide !
Je pensais à
Code :
1
2
3
 
CASE id IN (80,90,199,101)
WHEN SUM (...)
__________________
Alexandre T.

PHP5/MySQL5 Codes prêts à l'emploi
30 projets avec codes sources complets pour créer diaporamas photos, chat, arbre généalogique, statistiques de visites, création de graphiques, moteur de recherche, Sudoku etc...

Mes articles
Alexandre T est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2004, 10h24   #6
Provisoirement toléré
 
Avatar de Maximilian
 
Inscription : juin 2003
Messages : 2 622
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 2 622
Points : 2 505
Points : 2 505
Après vérification, un

Code :
1
2
SELECT sum(CASE WHEN x IN(...) THEN ... ) FROM y
GROUP BY z
fonctionne bien (mySQL 4.0).
Ca m'étonne parce qu'il me semble que j'avais déjà essayé, sans résultat. Enfin tant mieux

Au niveau de la vitesse, tout dépend du nombre de id_doc. S'il n'y en a que quelques-uns, il n'y aura pas grande différence entre calculer la somme dans la requête et dans le script PHP. Par contre s'il y en a des centaines, c'est sûr que ça économisera du transfert entre le serveur et le script.
Après, pour des calculs et traitements un peu complexes, je serais plutôt partisan de les laisser dans le code, pour des raisons de lisibilité. Après tout le langage SQL n'est pas tellement fait pour gérer la logique conditionnelle à la base...
__________________
Pensez au bouton
Maximilian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2004, 14h20   #7
Candidat au titre de Membre du Club
 
Inscription : mars 2004
Messages : 15
Détails du profil
Informations forums :
Inscription : mars 2004
Messages : 15
Points : 12
Points : 12
Excellent !!!

Ca marche !
en fait la table a environ 4'000 doc_id et 16'000 id ce qui fait environ 260'000 entrée en tout. (faut dire que c'est un peu une base test, la vrai sera plus petite).

Je vais faire des tests sur les différences de performences en temps entre les deux solution et je posterais les résultats si ca intéresse quelqu'un.

Mais ceci semble permettre de retourner que trente résultats ou avant il y avait 3'000 doc_id différents (donc beaucoup de communication inter-processus)..

Merci encore !
Synnalagma est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2004, 14h24   #8
Membre Expert
 
Avatar de Alexandre T
 
Inscription : mai 2002
Messages : 1 022
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France, Meurthe et Moselle (Lorraine)

Informations forums :
Inscription : mai 2002
Messages : 1 022
Points : 1 121
Points : 1 121
Citation:
Envoyé par Synnalagma
Je vais faire des tests sur les différences de performences en temps entre les deux solution et je posterais les résultats si ca intéresse quelqu'un.
Ah oui, les résultats m'intéresseraient. Merci de ton initiative.
__________________
Alexandre T.

PHP5/MySQL5 Codes prêts à l'emploi
30 projets avec codes sources complets pour créer diaporamas photos, chat, arbre généalogique, statistiques de visites, création de graphiques, moteur de recherche, Sudoku etc...

Mes articles
Alexandre T est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2004, 15h03   #9
Provisoirement toléré
 
Avatar de Maximilian
 
Inscription : juin 2003
Messages : 2 622
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 2 622
Points : 2 505
Points : 2 505
Citation:
Envoyé par Synnalagma
en fait la table a environ 4'000 doc_id et 16'000 id ce qui fait environ 260'000 entrée en tout.
Oui, là c'est sûr qu'il vaut mieux régler le maximum de choses directement dans la requête.

Citation:
Envoyé par Alexandre T
Citation:
Envoyé par Synnalagma
Je vais faire des tests sur les différences de performences en temps entre les deux solution et je posterais les résultats si ca intéresse quelqu'un.
Ah oui, les résultats m'intéresseraient. Merci de ton initiative.
Pareil, si tu peux nous tenir au courant...
__________________
Pensez au bouton
Maximilian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2004, 16h49   #10
Candidat au titre de Membre du Club
 
Inscription : mars 2004
Messages : 15
Détails du profil
Informations forums :
Inscription : mars 2004
Messages : 15
Points : 12
Points : 12
Bon voila quelque résultat sans que j'ai optimiser tous ce que ceci me permettra d'optmiser.


Les test ont été effectuer sur un ordinateur avec une mémoire de 256mb sur window$ ce qui explique les temps long. Auparavant j'avais regarder sur un ordi avec 512 sur linux le temp total était d'environ 1.3 secondes.
Requete SQL (requete avec environ 2500 résultat)
Code :
1
2
3
 
       avant         |        apres
 6.8 secondes           7.5 secondes
temp du Code PHP de traitement
Code :
1
2
3
 
       avant         |        apres
   4 secondes          presque 0 secondes
en tout
Code :
1
2
3
 
       avant         |        apres
   11 secondes          presque 7.5 secondes

Ca fait quand même une bonne amélioration des performences.

Si j'utilise LIMIT les temps descende vers un total de 4 seconde le probleme est que je dois connaitre le nombre de résultat total et qu'il n'est pas possible de l'avoir avec MySQL 3.23 (a ce que je sache).

Donc la toujours si vous avez des idées....

Merci encore
Synnalagma est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2004, 17h37   #11
Candidat au titre de Membre du Club
 
Inscription : mars 2004
Messages : 15
Détails du profil
Informations forums :
Inscription : mars 2004
Messages : 15
Points : 12
Points : 12
Tout ceci m'a permis de voir une optimisation absolument essentiel que j'aurais du voir plus tôt qui fait chuter considérablement les temps (valable que dans certains cas (les plus courants heureusement)).

A ce stade la différence est encore plus grande car j'arrive à 0.6 seconde pour la nouvelle méthode en tout

Alors que l'ancienne (mais optimisée) prend environ 4 secondes dont 1.5 seconde de requète sql ( soit 2.5 seconde de code php).
Synnalagma est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h32.


 
 
 
 
Partenaires

Hébergement Web