Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2658 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  Sortir requête SQL d'une boucle

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Sortir requête SQL d'une boucle

n°1784804
pouzy
Ne signe pas d'autographes..
Posté le 09-09-2008 à 23:57:58  profilanswer
 

Bonjour,
 
J'ai une requête SQL dans une boucle for, et j'aimerai l'en sortir (pour la santé de mon serveur je suppose que c'est ce qu'il faut faire).  
 
Voici la trame du code :  
 

Code :
  1. for($i=0;$i<$count;$i++)
  2.         {
  3.    //On regarde si l'enregistrement existe déjà
  4.    $result2 = mysql_query ("SELECT champ FROM table WHERE conditions", $xion);
  5.    $nb = mysql_num_rows($result2);
  6.    //Si oui
  7.      if( $nb > 0 )
  8.        {
  9.          //Ici requête UPDATE
  10.     $result = mysql_query("UPDATE table2 SET champ=champ+2 WHERE conditions", $xion);
  11.        } //Fin si enregistrement existe déjà
  12.        else
  13.        {
  14.        //Ici requête INSERT
  15.          $requete = "INSERT INTO table2 ( 1, 2, 3 ) VALUES ( 'var1', 'var2', 'var3' )";
  16.          $result = mysql_query ($requete, $xion);
  17.        }
  18. }


 
Quelqu'un aurait une idée pour rendre ça plus propre ? Parce que la, quand le for tourne longtemps ça peut faire mal, y a deux requêtes à chaque fois... Je suppose qu'on va m'insulter en disant que c'est dégueulasse, tout ça, donc... N'hésitez pas à me guider :)  
 
Merci !


---------------
Hello hello super jello
mood
Publicité
Posté le 09-09-2008 à 23:57:58  profilanswer
 

n°1784870
olivthill
Posté le 10-09-2008 à 10:17:10  profilanswer
 

Pour sortir d'une boucle, il suffit de mettre l'instruction break; comme vous le savez déjà certainement.
 
Pourquoi vouloir sortir de la boucle ?
 
* Parce que le traitement prendrait trop de temps ? Dans ce cas, pourquoi l'avoir commencé ?
Si l'on peut prévoir que le traiement va être long, on pourrait en avertir l'utilisateur à l'avance et lui demander une confirmation ou une annulation.
S'il confirme, pour le faire patienter, on pourrait mettre à jour un compteur Ajax.
 
* Parce que l'utilisateur voit qu'il est l'heure de partir, et préfère l'annuler pour le relancer le lendemain.
Le problème, c'est qu'il n'est pas facile de prendre en compte la décision d'interruption de l'utilisateur, car cette boucle tourne du côté du serveur, et les actions de l'utilisateur se font du côté client.

n°1784899
skeye
Posté le 10-09-2008 à 11:08:29  profilanswer
 

pouzy a écrit :

Bonjour,
 
J'ai une requête SQL dans une boucle for, et j'aimerai l'en sortir (pour la santé de mon serveur je suppose que c'est ce qu'il faut faire).  
 
Voici la trame du code :  
 

Code :
  1. for($i=0;$i<$count;$i++)
  2.         {
  3.    //On regarde si l'enregistrement existe déjà
  4.    $result2 = mysql_query ("SELECT champ FROM table WHERE conditions", $xion);
  5.    $nb = mysql_num_rows($result2);
  6.    //Si oui
  7.      if( $nb > 0 )
  8.        {
  9.          //Ici requête UPDATE
  10.     $result = mysql_query("UPDATE table2 SET champ=champ+2 WHERE conditions", $xion);
  11.        } //Fin si enregistrement existe déjà
  12.        else
  13.        {
  14.        //Ici requête INSERT
  15.          $requete = "INSERT INTO table2 ( 1, 2, 3 ) VALUES ( 'var1', 'var2', 'var3' )";
  16.          $result = mysql_query ($requete, $xion);
  17.        }
  18. }


 
Quelqu'un aurait une idée pour rendre ça plus propre ? Parce que la, quand le for tourne longtemps ça peut faire mal, y a deux requêtes à chaque fois... Je suppose qu'on va m'insulter en disant que c'est dégueulasse, tout ça, donc... N'hésitez pas à me guider :)  
 
Merci !


 
Difficile de répondre de manière précise sans avoir la vraie requête...elle dépend de ton $i? Si ce n'est pas le cas, il suffit de déplacer le code exécutant ton select au-dessus de la boucle, pour commencer.
Et si elle en dépend, n'y a-t'il pas un moyen simple d'obtenir tous tes résultats d'un seul coup et de boucler sur les résultats au lieu de faire une requête par valeur de $i?
De même, tu dois pouvoir ensuite faire tous tes insert d'un coup, et tous tes update d'un coup...


---------------
Can't buy what I want because it's free -
n°1784900
skeye
Posté le 10-09-2008 à 11:09:18  profilanswer
 

olivthill a écrit :

Pour sortir d'une boucle, il suffit de mettre l'instruction break; comme vous le savez déjà certainement.
 
Pourquoi vouloir sortir de la boucle ?
 
* Parce que le traitement prendrait trop de temps ? Dans ce cas, pourquoi l'avoir commencé ?
Si l'on peut prévoir que le traiement va être long, on pourrait en avertir l'utilisateur à l'avance et lui demander une confirmation ou une annulation.
S'il confirme, pour le faire patienter, on pourrait mettre à jour un compteur Ajax.
 
* Parce que l'utilisateur voit qu'il est l'heure de partir, et préfère l'annuler pour le relancer le lendemain.
Le problème, c'est qu'il n'est pas facile de prendre en compte la décision d'interruption de l'utilisateur, car cette boucle tourne du côté du serveur, et les actions de l'utilisateur se font du côté client.


Je pense que tu réponds à-coté de la question là - il souhaite sortir les requêtes de la boucle pour éviter de faire N requêtes et gagner en vitesse d'exécution, a priori.


---------------
Can't buy what I want because it's free -
n°1784901
omega2
Posté le 10-09-2008 à 11:12:53  profilanswer
 

olivthill > Réponse hors sujet, il demande comment mettre sa requête en dehors du for, pas comment quitter une boucle au milieu du traitement.
 
pouzy > Sans les vrai requêtes on ne peut pas t'aider. Comment veux tu qu'on te dise comment les adapter et surtout si il est possible de les adapter si tu nous donne des "SELECT champ FROM table WHERE conditions" qui n'a aucune saveur. C'est un peu comme demander à un garagiste comment réparer une voiture sans lui dire ce qui ne va pas.

n°1784906
olivthill
Posté le 10-09-2008 à 11:19:00  profilanswer
 

Excusez-moi !

n°1784912
infoman64
JE SUIS LA POUR TOI MON AMI
Posté le 10-09-2008 à 11:27:09  profilanswer
 

juste une question je voit pas l'interet de ton for avec tes requete,
tes requetes sont fixes(pas dynamique par rapport a ton for.)
pour moi a moins que je voit pas un truc,
tu fait x fois (où x est $count) la même opération.
Donc tu peut tout simplement virer ton For, il ne sert a rien a moins qu'il manque du code
 

n°1784914
infoman64
JE SUIS LA POUR TOI MON AMI
Posté le 10-09-2008 à 11:28:07  profilanswer
 

ah ok , je pense que c le "conditions",
j'avais pas vu autant pour moi

n°1785032
pouzy
Ne signe pas d'autographes..
Posté le 10-09-2008 à 14:51:35  profilanswer
 

Bonjour et merci de vous pencher sur ma question !  
 
En effet, j'ai été un peu léger sur les requêtes. Elles dépendent bel et bien du $i. Ce n'est pas face au visiteur que cela me gêne, mais face au serveur : cela peut faire beaucoup de requêtes d'un coup non ?  
 
 
Voici les vraies requêtes :
 
La premiere :

Code :
  1. mysql_query ("SELECT * FROM table WHERE idjoueur='".$id."' AND obj='".$tab[$i]."'", $idConnexion);


 
La deuxième :  
 

Code :
  1. if( $nb > 0 )
  2.        {
  3.          //Ici requête UPDATE
  4.     mysql_query("UPDATE table2 SET qtt=qtt+$tab[$i] WHERE id='" . $id ."' AND obj='" . $tab[$i] ."'", $xion);
  5.        }
  6.        else
  7.        {
  8.        //Ici requête INSERT
  9.          $requete = "INSERT INTO table ( obj, id, qtt ) VALUES ( '$tab[$i]', '$id', '$qtte[$i]' )";
  10.          $res = mysql_query ($requete, $xion);
  11.        }


 
Vous voyez donc que les requêtes dépendent du $i. Est-ce possible de ne faire qu'une grosse requête, plutôt que tout plein ?  
 
 
Merci !


---------------
Hello hello super jello
n°1785048
skeye
Posté le 10-09-2008 à 15:05:54  profilanswer
 

pouzy a écrit :


Code :
  1. mysql_query ("SELECT * FROM table WHERE idjoueur='".$id."' AND obj='".$tab[$i]."'", $idConnexion);


 

Celle-ci est très simple à sortir de la boucle, avec un simple

Code :
  1. AND obj IN(...)
 
pouzy a écrit :

Code :
  1. $requete = "INSERT INTO table ( obj, id, qtt ) VALUES ( '$tab[$i]', '$id', '$qtte[$i]' )";


 

tu peux insérer plusieurs lignes d'un coup, ça ne devrait pas poser de pb de la sortir de la boucle...

 


pouzy a écrit :

Code :
  1. mysql_query("UPDATE table2 SET qtt=qtt+$tab[$i] WHERE id='" . $id ."' AND obj='" . $tab[$i] ."'", $xion);


 

celle-ci c'est plus compliqué, ton $i intervenant à la fois dans le set et le where...


Message édité par skeye le 10-09-2008 à 15:06:32

---------------
Can't buy what I want because it's free -
mood
Publicité
Posté le 10-09-2008 à 15:05:54  profilanswer
 

n°1785055
omega2
Posté le 10-09-2008 à 15:14:10  profilanswer
 

Ta table, elle contient combien de lignes actuellement et ça représente quel poids dans mysql? Si la table est assez petite, tu peux toujours récupérer toute la table pour éviter de demander les données une par une.
Si $count est assez faible tu peux aussi ne demander que les données dont t'auras besoin ce qui évitera de récupérer plus d'informations que nécessaire.
 
Pour les requêtes d'insertions tu risques de ne pas gagner grand chose : j'imagine qu'il n'y aura pas beaucoup de créations par traitement. Toujours est il que tu peux te faire un tableau dans lequel tu te stockeras les nouveaux couples de joueur/objet avec la quantité qu'ils obtiennent (quantité à augmenter dans le tableau si cette quantité est censé augmenter plusieurs fois dans le traitement) Ensuite tu pourras tout créer en une seule requête (ou en plusieurs par bloc de n données si t'as plusieurs milliers de lignes à créer)
 
 
Pour les requêtes de mises à jours, c'est plus complexe :
- soit tu laisses tel quel
- soit tu fais un tableau dans lequel tu stockes les augmentations cumulés pour chaque couple de personne/objet qui voit sa quantité augmenter
Dans le second cas :
- soit tu fais ensuite une requête de mise à jour par couple/joueur (le plus simple mais ce qui fait gagner le moins de requête)
- soit tu dois retrier le tableau pour faire ensuite une mise à jour par augmentation de la quantité
 
 
Au final, si tu fais tout ça au pire tu diminueras le nombre de requêtes de moitié (cas où t'as au plus une création et aucun recoupement d'augmentation de quantité ni de couple joueur/objet) et au mieux t'en auras que trois à faire (la récupération des données, pas de création et les mises à jours des quantités si toutes les quantités augmentent de la même valeur) si t'as au moins une création de donnée.
 
PS: Pour la requête de sélection, il faut vérifier que ça ne ralentisse pas trop en récupérant tout ce dont on a besoin dès le début du traitement.
 
EDIT : J'ai été [:benou_grilled] dans l'ensemble en plus clair en plus.


Message édité par omega2 le 10-09-2008 à 15:15:48
n°1785293
Nasga
Posté le 10-09-2008 à 22:02:25  profilanswer
 

Alors, si j'ai bien tout compris :
 

Code :
  1. <?php
  2. /*
  3. * Tableau contenant les values
  4. */
  5. for($i=0;$i<count($tab);$i++) {
  6.     $arValues[] = $tab[$i].'","'.$id.'","'.$qtte[$i];
  7. }
  8. /*
  9. * Construction de la requete
  10. *
  11. * On fait tous les inserts en une seule requete (de bourrin)
  12. * Si on essaye d'insserer un couple id/obj existant on update (ON DUPLICATE),
  13. * Attention de bien placer un index UNIQUE sur les champs id/obj (un index pour les 2).
  14. */
  15. $sql  = 'INSERT INTO `table` (obj, id, qtt) VALUES ("';
  16. $sql .= implode('" ),("',$arValues);
  17. $sql .= '" ) ';
  18. $sql .= 'ON DUPLICATE KEY UPDATE SET qtt=qtt+VALUES(obj);';
  19. /*
  20. * On vide le (gros) tableau
  21. */
  22. unset($arValues);
  23. ?>


 
INSERT ON DUPLICATE est ton ami :)
Attention a tes index apparemment tu doit placer un champs unique sur id,obj (les deux groupé en un seul index).
 
Et si ma solution ne marche pas (j'ai pas assimilé le pourquoi du comment, juste le bout d'algo fournis), j'espère que ça va te rapprocher de la solution ^^


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  Sortir requête SQL d'une boucle

 

Sujets relatifs
[MySQL] Optimisation de requeteSQL Server concatener champ + chaine IMPOSSIBLE
Statistiques Php/Sql Allégéediteur requete intuitif
boucle sur pivottableWord & Publipostage SQL Server
conseil pour big requete SQLManipuler une BdD (Access ou SQL) en VBS
SQL reporting services, exporter rapport => XLS 
Plus de sujets relatifs à : Sortir requête SQL d'une boucle


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR