Page 1 sur 3

Programmer exécution de script sans cron

Posté : 26 avr. 2007, 21:06
par cicom
Bonjour à tous!
Voila pour mon jeu en ligne j'ai fait une belle fonction qui gère le temps qu'il fait sur la carte. Le principe c'est qu'elle s'exécute toutes les 24H pour que le temps change, le problème c'est qu'elle est lourde et que je ne voudrai pas que ce soit un utilisateur qui la lance grâce à une petite manipe (j'ai fait ca pour le bot, il "joue" quand un joueur se connecte et que ca fait 12h qu'il, le bot, a pas "joué")
Il faut qu'elle s'execute une fois par jour à 3h sans intervention de ma part.
Comme indiqué dans le titre je n'ai pas accès au cron (et pas à la commande linux non plus) alors comment faire?

Je fais suivre ma fonction meteo pour ceux que ca interesse
PS le temps d'exécution de cette fonction est supérieur à 10 sec et elle est amenée à être améliorée et à traiter plus de données...
function meteo ()
{
 $ndf = 1; //nombre de figures rentrées en array
 $figs = array();
 //syntaxe level x y
 //le rond
 $figs[0] = array();
 //zone noire
 $figs[0][0] = array();
 $figs[0][0][0] = 5;
 $figs[0][0][1] = 0;
 $figs[0][0][2] = 0;
 //zone bleue
 $figs[0][1] = array();
 $figs[0][1][1] = -1;
 $figs[0][1][2] = -1;
 $figs[0][2] = array();
 $figs[0][2][1] = 0;
 $figs[0][2][2] = -1;
 $figs[0][3] = array();
 $figs[0][3][1] = -2;
 $figs[0][3][2] = 0;
 $figs[0][4] = array();
 $figs[0][4][1] = -1;
 $figs[0][4][2] = 0;
 $figs[0][5] = array();
 $figs[0][5][1] = 1;
 $figs[0][5][2] = 0;
 $figs[0][6] = array();
 $figs[0][6][1] = -2;
 $figs[0][6][2] = 1;
 $figs[0][7] = array();
 $figs[0][7][1] = -1;
 $figs[0][7][2] = 1;
 $figs[0][8] = array();
 $figs[0][8][1] = 0;
 $figs[0][8][2] = 1;
 $figs[0][9] = array();
 $figs[0][9][1] = 1;
 $figs[0][9][2] = 1;
 $figs[0][10] = array();
 $figs[0][10][1] = -1;
 $figs[0][10][2] = 2;
 $figs[0][11] = array();
 $figs[0][11][1] = 0;
 $figs[0][11][2] = 2;
 //zone rouge
 $figs[0][12] = array();
 $figs[0][12][1] = -1;
 $figs[0][12][2] = -2;
 $figs[0][13] = array();
 $figs[0][13][1] = 0;
 $figs[0][13][2] = -2;
 $figs[0][14] = array();
 $figs[0][14][1] = 1;
 $figs[0][14][2] = -1;
 $figs[0][15] = array();
 $figs[0][15][1] = 2;
 $figs[0][15][2] = 0;
 $figs[0][16] = array();
 $figs[0][16][1] = 2;
 $figs[0][16][2] = 1;
 $figs[0][17] = array();
 $figs[0][17][1] = 1;
 $figs[0][17][2] = 2;
 $figs[0][18] = array();
 $figs[0][18][1] = 0;
 $figs[0][18][2] = 3;
 $figs[0][19] = array();
 $figs[0][19][0] = 3;
 $figs[0][19][1] = -1;
 $figs[0][19][2] = 3;
 $figs[0][20] = array();
 $figs[0][20][1] = -2;
 $figs[0][20][2] = 2;
 $figs[0][21] = array();
 $figs[0][21][1] = -3;
 $figs[0][21][2] = 1;
 $figs[0][22] = array();
 $figs[0][22][1] = -3;
 $figs[0][22][2] = 0;
 $figs[0][23] = array();
 $figs[0][23][1] = -2;
 $figs[0][23][2] = -1;
 //zone jaune
 $figs[0][24] = array();
 $figs[0][24][1] = -1;
 $figs[0][24][2] = -3;
 $figs[0][25] = array();
 $figs[0][25][1] = 0;
 $figs[0][25][2] = -3;
 $figs[0][26] = array();
 $figs[0][26][1] = 1;
 $figs[0][26][2] = -2;
 $figs[0][27] = array();
 $figs[0][27][1] = 2;
 $figs[0][27][2] = -1;
 $figs[0][28] = array();
 $figs[0][28][1] = 3;
 $figs[0][28][2] = 0;
 $figs[0][29] = array();
 $figs[0][29][1] = 3;
 $figs[0][29][2] = 1;
 $figs[0][30] = array();
 $figs[0][30][1] = 2;
 $figs[0][30][2] = 2;
 $figs[0][31] = array();
 $figs[0][31][1] = 1;
 $figs[0][31][2] = 3;
 $figs[0][32] = array();
 $figs[0][32][1] = 0;
 $figs[0][32][2] = 4;
 $figs[0][33] = array();
 $figs[0][33][1] = -1;
 $figs[0][33][2] = 4;
 $figs[0][34] = array();
 $figs[0][34][1] = -2;
 $figs[0][34][2] = 3;
 $figs[0][35] = array();
 $figs[0][35][1] = -3;
 $figs[0][35][2] = 2;
 $figs[0][36] = array();
 $figs[0][36][1] = -4;
 $figs[0][36][2] = 1;
 $figs[0][37] = array();
 $figs[0][37][1] = -4;
 $figs[0][37][2] = 0;
 $figs[0][38] = array();
 $figs[0][38][1] = -3;
 $figs[0][38][2] = -1;
 $figs[0][39] = array();
 $figs[0][39][1] = -2;
 $figs[0][39][2] = -2;
 //zone verte
 $figs[0][40] = array();
 $figs[0][40][1] = -1;
 $figs[0][40][2] = -4;
 $figs[0][41] = array();
 $figs[0][41][1] = 0;
 $figs[0][41][2] = -4;
 $figs[0][42] = array();
 $figs[0][42][1] = 1;
 $figs[0][42][2] = -3;
 $figs[0][43] = array();
 $figs[0][43][1] = 2;
 $figs[0][43][2] = -2;
 $figs[0][44] = array();
 $figs[0][44][1] = 3;
 $figs[0][44][2] = -1;
 $figs[0][45] = array();
 $figs[0][45][1] = 4;
 $figs[0][45][2] = 1;
 $figs[0][46] = array();
 $figs[0][46][1] = 4;
 $figs[0][46][2] = 1;
 $figs[0][47] = array();
 $figs[0][47][1] = 3;
 $figs[0][47][2] = 2;
 $figs[0][48] = array();
 $figs[0][48][1] = 2;
 $figs[0][48][2] = 3;
 $figs[0][49] = array();
 $figs[0][49][1] = 1;
 $figs[0][49][2] = 4;
 $figs[0][50] = array();
 $figs[0][50][1] = 0;
 $figs[0][50][2] = 5;
 $figs[0][51] = array();
 $figs[0][51][1] = -1;
 $figs[0][51][2] = 5;
 $figs[0][52] = array();
 $figs[0][52][1] = -2;
 $figs[0][52][2] = 4;
 $figs[0][53] = array();
 $figs[0][53][1] = -3;
 $figs[0][53][2] = 3;
 $figs[0][54] = array();
 $figs[0][54][1] = -4;
 $figs[0][54][2] = 2;
 $figs[0][55] = array();
 $figs[0][55][1] = -5;
 $figs[0][55][2] = 1;
 $figs[0][56] = array();
 $figs[0][56][1] = -5;
 $figs[0][56][2] = 0;
 $figs[0][57] = array();
 $figs[0][57][1] = -4;
 $figs[0][57][2] = -1;
 $figs[0][58] = array();
 $figs[0][58][1] = -3;
 $figs[0][58][2] = -2;
 $figs[0][59] = array();
 $figs[0][59][1] = -2;
 $figs[0][59][2] = -3;
 //DEV boucles pour gagner du temps
 $car4 = 0;
 while($car4 < 10) //zone bleue
 {
  $car4++;
  $figs[0][$car4][0] = 4;
 }
 $car3 = 11;
 while($car3 < 22) // zone rouge
 {
  $car3++;
  $figs[0][$car3][0] = 3;
 }
 $car2 = 23;
 while($car2 < 38) //zone jaune
 {
  $car2++;
  $figs[0][$car2][0] = 2;
 }
 $car1 = 39;
 while($car1 < 59) //zone verte
 {
  $car1++;
  $figs[0][$car1][0] = 1;
 }
 //SUITE DEV FINIR ZONES
 
 $ndf--;
 $sql1 = mysql_query("SELECT count(*) FROM map");
 $sql2 = mysql_result($sql1, 0, 0);
 $nbact = floor($sql2 / 60);
 $curseur = 0;
 $arid = array();
 $caid = -1;
 while($nbact > $curseur)
 {
  $rdf = rand(0, $ndf);
  $sql3 = mysql_query("SELECT x, y FROM meteo ORDER BY rand() LIMIT 1");
  $sql4 = mysql_fetch_array($sql3);
  $c2 = -1;
  $rtemps = rand(0, 3);
  if($rtemps == 0) { $temps = 'brouillard'; }
  if($rtemps == 1) { $temps = 'neige'; }
  if($rtemps == 2) { $temps = 'pluie'; }
  if($rtemps == 3) { $temps = 'pluie'; }
  while($c2 < 59)
  {
   $c2++;
   $xf = $sql4['x'] + $figs[$rdf][$c2][1];
   $yf = $sql4['y'] + $figs[$rdf][$c2][2];
   mysql_query("UPDATE meteo SET temps = '".$temps."', level = '".$figs[$rdf][$c2][0]."' WHERE y = '".$yf."' AND x = '".$xf."'");
   $asql1 = mysql_query("SELECT id FROM meteo WHERE y = '".$yf."' AND x = '".$xf."'");
   $asql2 = mysql_fetch_array($asql1);
   $caid++;
   $arid[$caid] = $asql2['id'];
  }
  $curseur++;
 }
 $bsql1 = mysql_query("SELECT id FROM meteo");
 while($bsql2 = mysql_fetch_array($bsql1);)
 {
  $c3 = -1;
  $verrif = 0;
  while($c3 < $caid)
  {
   $c3++;
   if($arid[$c3] == $bsql2['id'])
   {
    $verrif = 1;
   }
  }
  if($verrif == 0)
  {
   mysql_query("UPDATE meteo SET temps = 'beau', level = '0' WHERE id = '".$bsql2['id']."'");
  }
 }
 mysql_query("UPDATE meteo SET temps = 'beau', level = '0' WHERE temps = 'null'");
}

Posté : 27 avr. 2007, 01:03
par zigz4g
http://www.webcron.org
C'est encore d'actualité ce site ?

Posté : 27 avr. 2007, 10:24
par cicom
Ca a l'air de marcher merci beaucoup!
Je mets résolu et je reviendrai ici si jamais ce n'est pas le cas...

Posté : 27 avr. 2007, 10:46
par naholyr
Je pense qu'il faudrait aussi refléchir à comment optimiser tout ça.
Il faut toujours refléchir à sortir le plus possible les requêtes des boucles.

Pour la deuxième boucle c'est trivial puisque tu n'as que la clause WHERE qui change (c'est trivial quand tu as la condition OU l'action qui est la même pour toutes les requêtes de la boucle).
Voici le principe :
// je dois mettre "flag" à 1 pour tous les numeros entre 1 et 100
// je parcours donc tous les numéros
for ($i=1; $i<=100; $i++) {
    // pour chaque, je fais la requête
    mysql_query("UPDATE matable SET modifie='oui' WHERE numero=$i");
}
// je viens de faire 100 requêtes *gulp*
// je dois mettre "flag" à 1 pour tous les numeros entre 1 et 100
// je prépare la liste des clauses WHERE concernées :
$where = array();
// je parcours tous les numéros
for ($i=1; $i<=100; $i++) {
    // pour chaque, je rajoute la clause WHERE
    $where[] = "numero=$i";
}
// je construis ma requête
$query = "UPDATE matable SET modifie='oui' WHERE (" . implode(") OR (", $where) . ")";
mysql_query($query);
// je viens de faire 100 fois moins de requêtes
Le gain n'est pas de 100 pour 1, car au lieu de 100 petites on fait une très grosse (100 conditions c'est assez lourd) mais on n'est tout de même pas loin du 100 pour 1 car le coût le plus élevé dans la requête c'est plus l'appel à mysql_query() que la requête elle-même.

Pour la première boucle c'est moins trivial, et c'est pourtant là qu'il y a le plus gros à faire, tu as une boucle, une requête dans cette boucle, puis une boucle imbriquée, et deux requêtes dans cette boucle imbriquée :O
Il faut absolument revoir ton algorithme à ce niveau. Il y a des sorties de boucle triviales dans le lot, ce sera déjà ça de gagné.

Ensuite pour les UPDATE dans des boucles qui n'ont ni action ni clause WHERE fixe en commun, mais que les champs de la clause WHERE sont toujours les mêmes, tu peux jouer avec REPLACE, par exemple :

Code : Tout sélectionner

UPDATE matable SET flag=1 WHERE x=3 AND y=4
sera équivalent à (mais beaucoup moins performant) :

Code : Tout sélectionner

REPLACE INTO matable (flag,x,y) VALUES (1,3,4)
à condition qu'il y ait un index UNIQUE sur x,y et que les valeurs x=3,y=4 soient déjà dans la table.

En fait REPLACE sert à faire des INSERT "doublon-proof" : s'il n'y a pas conflit avec un (ou des) index UNIQUE il insère, s'il y a conflit il fait un UPDATE basé sur cet (ou ces) index. Dans notre cas on s'assure qu'il y a conflit afin de faire un UPDATE. L'intérêt étant qu'on pourra faire un REPLACE multiple variant à la fois les valeurs mises à jour et les valeurs de la condition, ce que ne permet pas un UPDATE.

Ainsi, si le REPLACE est moins performant que l'UPDATE (il est plutôt là pour apporter du confort que de la performance), un seul REPLACE sera beaucoup plus performant qu'une centaine d'UPDATES ;)
Donc ça peut valoir le coup (à étudier !) de remplacer
for ($i=0; $i<100; $i++) {
    mysql_query("UPDATE matable SET flag=".mt_rand(0,1)." WHERE numero=$i");
}
par ce code et un index UNIQUE sur 'numero' (les champs de la clause WHERE)
$values = array();
for ($i=0; $i<100; $i++) {
    $values[] = mt_rand(0,1).",$i";
}
$query = "REPLACE INTO matable (flag,numero) VALUES (" . implode("),(", $values) . ")";
mysql_query($query);
Fais déjà ces sorties de boucles, et vois si tu ne peux pas en faire encore un peu plus en refléchissant à d'autres optimisations, voire à une optimisation de l'algorithme lui-même.

Posté : 27 avr. 2007, 11:36
par cicom
Re,
Ouh là tu me demandes de faire du grand art là! :wink:
Y a t'il une limite de nombre de caratère dans une requète MySQL? Parce que la technique du implode est pas mal le seul problème c'est que ma table météo comporte actuellement 1600 enregistrements et elle devra au final en comporter à peu près 100 000 (ou plus ca dépendra du nombre de joueurs au final...)
S'il y a effectivement une limite je ferai mieux de ne pas changer mon système, car même s'il est lourd, il est illimité et tout le jeu est construit comme ca, on est limité par rien sauf par la capacité du server.
Qu'en penses-tu?

Le temps d'execution de la page est de 9 secondes et je joint la dernière version de la fonction corrigée et réglée (pour que ca colle un peu plus à la réalité et j'ai corrigé une erreur php)
Et c'est bien la partie sql de la fonciton qui prend du temps, j'ai fait un test sans cette partie l'execution est instantannée...

Je pense qu'on a un moyen facile d'économiser beaucoup le server à ce moment là
mysql_query("UPDATE meteo SET temps = '".$temps."', level = '".$figs[$rdf][$c2][0]."' WHERE y = '".$yf."' AND x = '".$xf."'");
   $asql1 = mysql_query("SELECT id FROM meteo WHERE y = '".$yf."' AND x = '".$xf."'"); 
Si on pouvait sélectionner l'id tout en modifiant le temps et le level on y gagnerait. C'est possible?
function meteo ()
{
 $ndf = 1; //nombre de figures rentrées en array
 $figs = array();
 //syntaxe level x y
 //le rond
 $figs[0] = array();
 //zone noire
 $figs[0][0] = array();
 $figs[0][0][0] = 5;
 $figs[0][0][1] = 0;
 $figs[0][0][2] = 0;
 //zone bleue
 $figs[0][1] = array();
 $figs[0][1][1] = -1;
 $figs[0][1][2] = -1;
 $figs[0][2] = array();
 $figs[0][2][1] = 0;
 $figs[0][2][2] = -1;
 $figs[0][3] = array();
 $figs[0][3][1] = -2;
 $figs[0][3][2] = 0;
 $figs[0][4] = array();
 $figs[0][4][1] = -1;
 $figs[0][4][2] = 0;
 $figs[0][5] = array();
 $figs[0][5][1] = 1;
 $figs[0][5][2] = 0;
 $figs[0][6] = array();
 $figs[0][6][1] = -2;
 $figs[0][6][2] = 1;
 $figs[0][7] = array();
 $figs[0][7][1] = -1;
 $figs[0][7][2] = 1;
 $figs[0][8] = array();
 $figs[0][8][1] = 0;
 $figs[0][8][2] = 1;
 $figs[0][9] = array();
 $figs[0][9][1] = 1;
 $figs[0][9][2] = 1;
 $figs[0][10] = array();
 $figs[0][10][1] = -1;
 $figs[0][10][2] = 2;
 $figs[0][11] = array();
 $figs[0][11][1] = 0;
 $figs[0][11][2] = 2;
 //zone rouge
 $figs[0][12] = array();
 $figs[0][12][1] = -1;
 $figs[0][12][2] = -2;
 $figs[0][13] = array();
 $figs[0][13][1] = 0;
 $figs[0][13][2] = -2;
 $figs[0][14] = array();
 $figs[0][14][1] = 1;
 $figs[0][14][2] = -1;
 $figs[0][15] = array();
 $figs[0][15][1] = 2;
 $figs[0][15][2] = 0;
 $figs[0][16] = array();
 $figs[0][16][1] = 2;
 $figs[0][16][2] = 1;
 $figs[0][17] = array();
 $figs[0][17][1] = 1;
 $figs[0][17][2] = 2;
 $figs[0][18] = array();
 $figs[0][18][1] = 0;
 $figs[0][18][2] = 3;
 $figs[0][19] = array();
 $figs[0][19][0] = 3;
 $figs[0][19][1] = -1;
 $figs[0][19][2] = 3;
 $figs[0][20] = array();
 $figs[0][20][1] = -2;
 $figs[0][20][2] = 2;
 $figs[0][21] = array();
 $figs[0][21][1] = -3;
 $figs[0][21][2] = 1;
 $figs[0][22] = array();
 $figs[0][22][1] = -3;
 $figs[0][22][2] = 0;
 $figs[0][23] = array();
 $figs[0][23][1] = -2;
 $figs[0][23][2] = -1;
 //zone jaune
 $figs[0][24] = array();
 $figs[0][24][1] = -1;
 $figs[0][24][2] = -3;
 $figs[0][25] = array();
 $figs[0][25][1] = 0;
 $figs[0][25][2] = -3;
 $figs[0][26] = array();
 $figs[0][26][1] = 1;
 $figs[0][26][2] = -2;
 $figs[0][27] = array();
 $figs[0][27][1] = 2;
 $figs[0][27][2] = -1;
 $figs[0][28] = array();
 $figs[0][28][1] = 3;
 $figs[0][28][2] = 0;
 $figs[0][29] = array();
 $figs[0][29][1] = 3;
 $figs[0][29][2] = 1;
 $figs[0][30] = array();
 $figs[0][30][1] = 2;
 $figs[0][30][2] = 2;
 $figs[0][31] = array();
 $figs[0][31][1] = 1;
 $figs[0][31][2] = 3;
 $figs[0][32] = array();
 $figs[0][32][1] = 0;
 $figs[0][32][2] = 4;
 $figs[0][33] = array();
 $figs[0][33][1] = -1;
 $figs[0][33][2] = 4;
 $figs[0][34] = array();
 $figs[0][34][1] = -2;
 $figs[0][34][2] = 3;
 $figs[0][35] = array();
 $figs[0][35][1] = -3;
 $figs[0][35][2] = 2;
 $figs[0][36] = array();
 $figs[0][36][1] = -4;
 $figs[0][36][2] = 1;
 $figs[0][37] = array();
 $figs[0][37][1] = -4;
 $figs[0][37][2] = 0;
 $figs[0][38] = array();
 $figs[0][38][1] = -3;
 $figs[0][38][2] = -1;
 $figs[0][39] = array();
 $figs[0][39][1] = -2;
 $figs[0][39][2] = -2;
 //zone verte
 $figs[0][40] = array();
 $figs[0][40][1] = -1;
 $figs[0][40][2] = -4;
 $figs[0][41] = array();
 $figs[0][41][1] = 0;
 $figs[0][41][2] = -4;
 $figs[0][42] = array();
 $figs[0][42][1] = 1;
 $figs[0][42][2] = -3;
 $figs[0][43] = array();
 $figs[0][43][1] = 2;
 $figs[0][43][2] = -2;
 $figs[0][44] = array();
 $figs[0][44][1] = 3;
 $figs[0][44][2] = -1;
 $figs[0][45] = array();
 $figs[0][45][1] = 4;
 $figs[0][45][2] = 1;
 $figs[0][46] = array();
 $figs[0][46][1] = 4;
 $figs[0][46][2] = 1;
 $figs[0][47] = array();
 $figs[0][47][1] = 3;
 $figs[0][47][2] = 2;
 $figs[0][48] = array();
 $figs[0][48][1] = 2;
 $figs[0][48][2] = 3;
 $figs[0][49] = array();
 $figs[0][49][1] = 1;
 $figs[0][49][2] = 4;
 $figs[0][50] = array();
 $figs[0][50][1] = 0;
 $figs[0][50][2] = 5;
 $figs[0][51] = array();
 $figs[0][51][1] = -1;
 $figs[0][51][2] = 5;
 $figs[0][52] = array();
 $figs[0][52][1] = -2;
 $figs[0][52][2] = 4;
 $figs[0][53] = array();
 $figs[0][53][1] = -3;
 $figs[0][53][2] = 3;
 $figs[0][54] = array();
 $figs[0][54][1] = -4;
 $figs[0][54][2] = 2;
 $figs[0][55] = array();
 $figs[0][55][1] = -5;
 $figs[0][55][2] = 1;
 $figs[0][56] = array();
 $figs[0][56][1] = -5;
 $figs[0][56][2] = 0;
 $figs[0][57] = array();
 $figs[0][57][1] = -4;
 $figs[0][57][2] = -1;
 $figs[0][58] = array();
 $figs[0][58][1] = -3;
 $figs[0][58][2] = -2;
 $figs[0][59] = array();
 $figs[0][59][1] = -2;
 $figs[0][59][2] = -3;
 //DEV boucles pour gagner du temps
 $car4 = 0;
 while($car4 < 10) //zone bleue
 {
  $car4++;
  $figs[0][$car4][0] = 4;
 }
 $car3 = 11;
 while($car3 < 22) // zone rouge
 {
  $car3++;
  $figs[0][$car3][0] = 3;
 }
 $car2 = 23;
 while($car2 < 38) //zone jaune
 {
  $car2++;
  $figs[0][$car2][0] = 2;
 }
 $car1 = 39;
 while($car1 < 59) //zone verte
 {
  $car1++;
  $figs[0][$car1][0] = 1;
 }
 //SUITE DEV FINIR ZONES
 
 $ndf--;
 $sql1 = mysql_query("SELECT count(*) FROM map");
 $sql2 = mysql_result($sql1, 0, 0);
 $nbact = floor(($sql2 / 60) /1.3 );
 $curseur = 0;
 $arid = array();
 $caid = -1;
 while($nbact > $curseur)
 {
  $rdf = rand(0, $ndf);
  $sql3 = mysql_query("SELECT x, y FROM meteo ORDER BY rand() LIMIT 1");
  $sql4 = mysql_fetch_array($sql3);
  $c2 = -1;
  $rtemps = rand(0, 3);
  if($rtemps == 0) { $temps = 'brouillard'; }
  if($rtemps == 1) { $temps = 'neige'; }
  if($rtemps == 2) { $temps = 'pluie'; }
  if($rtemps == 3) { $temps = 'pluie'; }
  while($c2 < 59)
  {
   $c2++;
   $xf = $sql4['x'] + $figs[$rdf][$c2][1];
   $yf = $sql4['y'] + $figs[$rdf][$c2][2];
   mysql_query("UPDATE meteo SET temps = '".$temps."', level = '".$figs[$rdf][$c2][0]."' WHERE y = '".$yf."' AND x = '".$xf."'");
   $asql1 = mysql_query("SELECT id FROM meteo WHERE y = '".$yf."' AND x = '".$xf."'");
   $asql2 = mysql_fetch_array($asql1);
   $caid++;
   $arid[$caid] = $asql2['id'];
  }
  $curseur++;
 }
 $bsql1 = mysql_query("SELECT id FROM meteo");
 while($bsql2 = mysql_fetch_array($bsql1))
 {
  $c3 = -1;
  $verrif = 0;
  while($c3 < $caid)
  {
   $c3++;
   if($arid[$c3] == $bsql2['id'])
   {
    $verrif = 1;
   }
  }
  if($verrif == 0)
  {
   mysql_query("UPDATE meteo SET temps = 'beau', level = '0' WHERE id = '".$bsql2['id']."'");
  }
 }
 mysql_query("UPDATE meteo SET temps = 'beau', level = '0' WHERE temps = 'null'");
}
[/php]

Posté : 27 avr. 2007, 11:51
par naholyr
Y a t'il une limite de nombre de caratère dans une requète MySQL?
Pas de limite à ma connaissance, j'ai un script sur un serveur qui fait regulièrement des requêtes de plusieurs centaines de Ko, et ça ne pose pas de problème particulier.

Pour le reste : pas le temps maintenant :)

Posté : 27 avr. 2007, 13:48
par cicom
Re,
On a gagné une demie seconde en temps d'exécution, la fonction implode doit être sacrément gourmande... J'ai aussi pensé qu'on pouvait se passer des paranthèses histoires de gagner encore quelques octects en transmition.
Je m'attaque au replace pour voir ce que ça donne, je n'ai encore jamais utilisé cette fonction mysql...
Pour les id quelqu'un a une idée? (cf ma réponse précédente)
Merci à tous!

Posté : 27 avr. 2007, 14:02
par cicom
Re,
Le replace me crée des doublons, mettons par exemple que j'ai un enregistrement qui est
id = 1
x = 0
y = 0
temps = 'beau'
level = 0

si je fais REPLACE INTO meteo (temps,level,x,y) VALUES ('pluie',3,0,0) il va me créer un doublon au lieu de me passer cette case à l'état pluie de niveau 3...
J'ai fait une erreur? une idée?
Merci!

Posté : 27 avr. 2007, 14:10
par naholyr
si je fais REPLACE INTO meteo (temps,level,x,y) VALUES ('pluie',3,0,0) il va me créer un doublon au lieu de me passer cette case à l'état pluie de niveau 3...
J'ai fait une erreur? une idée?
Tu n'as pas lu pourtant la phrase qui était pourtant la seule à être en gras dans mon message...
Re,
On a gagné une demie seconde en temps d'exécution, la fonction implode doit être sacrément gourmande...
Excuse-moi j'ai faux dans mon optimisation, quand on a plein de OR comme ça sur des conditions d'égalité sur un seul champ, il faut absolument les remplacer par un IN :

Code : Tout sélectionner

(a=1) OR (a=2) OR (a=3)
deviendra

Code : Tout sélectionner

a IN (1,2,3)
Donc l'optimisation que je proposais aurait du être :
// je dois mettre "flag" à 1 pour tous les numeros entre 1 et 100
// je prépare la liste des valeurs de mon champ de référence
$valeurs = array();
// je parcours tous les numéros
for ($i=1; $i<=100; $i++) {
    // pour chaque, je rajoute la clause WHERE
    $valeurs[] = $i;
}
// je construis ma requête
$query = "UPDATE matable SET modifie='oui' WHERE numero IN (" . implode(",", $valeurs) . ")";
mysql_query($query);
Tu vas voir que ça réduit le temps d'exécution.

Par contre ce n'est de toute façon pas cette boucle qui consomme le plus (encore que toute économie est bonne à faire dans ce domaine).

Posté : 27 avr. 2007, 14:20
par sadeq
Pour revenir à la boucle des 100 requêtes ...

Puisque c'est une suite arithmétique on peut se passer même de la boucle tout en exécutant la requête une seule fois:

Ancien:
// je dois mettre "flag" à 1 pour tous les numeros entre 1 et 100 
// je parcours donc tous les numéros 
for ($i=1; $i<=100; $i++) { 
    // pour chaque, je fais la requête 
    mysql_query("UPDATE matable SET modifie='oui' WHERE numero=$i"); 
} 
// je viens de faire 100 requêtes *gulp*
Nouveau:
mysql_query("UPDATE matable SET modifie='oui' WHERE numero Between 0 AND 100"); 

Posté : 27 avr. 2007, 14:41
par cicom
Re,
Naholyr => Effectivement on gagne encore 0.3 secondes pour le IN
L'index c'est bien l'id? (ou alors j'ai mal compris le fonctionement de Mysql) et dans mon cas il y a qu'un seul id par enregistrement donc ma table marche avec un index unique.

Sadeq => Merci de ta proposition mais malheursement je ne pourrait pas l'appliquer à mon cas, car je crois ta solution implique que les id se suivent ce qui n'est pas mon cas (on va s'occuper du 4 puis du 30 même s'i ly en a 25 autres entre eux ou même s'il y en a 23 autres et 2 qui ont été supprimés...)

Voila, Naholyr ou quelqu'un pourrait il m'expliquer l'histoire des index unique car je sens que j'ai raté quelque chose la...
Merci à tous!

Dernière version du script
function meteo ()
{
 $ndf = 1; //nombre de figures rentrées en array
 $figs = array();
 //syntaxe level x y
 //le rond
 $figs[0] = array();
 //zone noire
 $figs[0][0] = array();
 $figs[0][0][0] = 5;
 $figs[0][0][1] = 0;
 $figs[0][0][2] = 0;
 //zone bleue
 $figs[0][1] = array();
 $figs[0][1][1] = -1;
 $figs[0][1][2] = -1;
 $figs[0][2] = array();
 $figs[0][2][1] = 0;
 $figs[0][2][2] = -1;
 $figs[0][3] = array();
 $figs[0][3][1] = -2;
 $figs[0][3][2] = 0;
 $figs[0][4] = array();
 $figs[0][4][1] = -1;
 $figs[0][4][2] = 0;
 $figs[0][5] = array();
 $figs[0][5][1] = 1;
 $figs[0][5][2] = 0;
 $figs[0][6] = array();
 $figs[0][6][1] = -2;
 $figs[0][6][2] = 1;
 $figs[0][7] = array();
 $figs[0][7][1] = -1;
 $figs[0][7][2] = 1;
 $figs[0][8] = array();
 $figs[0][8][1] = 0;
 $figs[0][8][2] = 1;
 $figs[0][9] = array();
 $figs[0][9][1] = 1;
 $figs[0][9][2] = 1;
 $figs[0][10] = array();
 $figs[0][10][1] = -1;
 $figs[0][10][2] = 2;
 $figs[0][11] = array();
 $figs[0][11][1] = 0;
 $figs[0][11][2] = 2;
 //zone rouge
 $figs[0][12] = array();
 $figs[0][12][1] = -1;
 $figs[0][12][2] = -2;
 $figs[0][13] = array();
 $figs[0][13][1] = 0;
 $figs[0][13][2] = -2;
 $figs[0][14] = array();
 $figs[0][14][1] = 1;
 $figs[0][14][2] = -1;
 $figs[0][15] = array();
 $figs[0][15][1] = 2;
 $figs[0][15][2] = 0;
 $figs[0][16] = array();
 $figs[0][16][1] = 2;
 $figs[0][16][2] = 1;
 $figs[0][17] = array();
 $figs[0][17][1] = 1;
 $figs[0][17][2] = 2;
 $figs[0][18] = array();
 $figs[0][18][1] = 0;
 $figs[0][18][2] = 3;
 $figs[0][19] = array();
 $figs[0][19][0] = 3;
 $figs[0][19][1] = -1;
 $figs[0][19][2] = 3;
 $figs[0][20] = array();
 $figs[0][20][1] = -2;
 $figs[0][20][2] = 2;
 $figs[0][21] = array();
 $figs[0][21][1] = -3;
 $figs[0][21][2] = 1;
 $figs[0][22] = array();
 $figs[0][22][1] = -3;
 $figs[0][22][2] = 0;
 $figs[0][23] = array();
 $figs[0][23][1] = -2;
 $figs[0][23][2] = -1;
 //zone jaune
 $figs[0][24] = array();
 $figs[0][24][1] = -1;
 $figs[0][24][2] = -3;
 $figs[0][25] = array();
 $figs[0][25][1] = 0;
 $figs[0][25][2] = -3;
 $figs[0][26] = array();
 $figs[0][26][1] = 1;
 $figs[0][26][2] = -2;
 $figs[0][27] = array();
 $figs[0][27][1] = 2;
 $figs[0][27][2] = -1;
 $figs[0][28] = array();
 $figs[0][28][1] = 3;
 $figs[0][28][2] = 0;
 $figs[0][29] = array();
 $figs[0][29][1] = 3;
 $figs[0][29][2] = 1;
 $figs[0][30] = array();
 $figs[0][30][1] = 2;
 $figs[0][30][2] = 2;
 $figs[0][31] = array();
 $figs[0][31][1] = 1;
 $figs[0][31][2] = 3;
 $figs[0][32] = array();
 $figs[0][32][1] = 0;
 $figs[0][32][2] = 4;
 $figs[0][33] = array();
 $figs[0][33][1] = -1;
 $figs[0][33][2] = 4;
 $figs[0][34] = array();
 $figs[0][34][1] = -2;
 $figs[0][34][2] = 3;
 $figs[0][35] = array();
 $figs[0][35][1] = -3;
 $figs[0][35][2] = 2;
 $figs[0][36] = array();
 $figs[0][36][1] = -4;
 $figs[0][36][2] = 1;
 $figs[0][37] = array();
 $figs[0][37][1] = -4;
 $figs[0][37][2] = 0;
 $figs[0][38] = array();
 $figs[0][38][1] = -3;
 $figs[0][38][2] = -1;
 $figs[0][39] = array();
 $figs[0][39][1] = -2;
 $figs[0][39][2] = -2;
 //zone verte
 $figs[0][40] = array();
 $figs[0][40][1] = -1;
 $figs[0][40][2] = -4;
 $figs[0][41] = array();
 $figs[0][41][1] = 0;
 $figs[0][41][2] = -4;
 $figs[0][42] = array();
 $figs[0][42][1] = 1;
 $figs[0][42][2] = -3;
 $figs[0][43] = array();
 $figs[0][43][1] = 2;
 $figs[0][43][2] = -2;
 $figs[0][44] = array();
 $figs[0][44][1] = 3;
 $figs[0][44][2] = -1;
 $figs[0][45] = array();
 $figs[0][45][1] = 4;
 $figs[0][45][2] = 1;
 $figs[0][46] = array();
 $figs[0][46][1] = 4;
 $figs[0][46][2] = 1;
 $figs[0][47] = array();
 $figs[0][47][1] = 3;
 $figs[0][47][2] = 2;
 $figs[0][48] = array();
 $figs[0][48][1] = 2;
 $figs[0][48][2] = 3;
 $figs[0][49] = array();
 $figs[0][49][1] = 1;
 $figs[0][49][2] = 4;
 $figs[0][50] = array();
 $figs[0][50][1] = 0;
 $figs[0][50][2] = 5;
 $figs[0][51] = array();
 $figs[0][51][1] = -1;
 $figs[0][51][2] = 5;
 $figs[0][52] = array();
 $figs[0][52][1] = -2;
 $figs[0][52][2] = 4;
 $figs[0][53] = array();
 $figs[0][53][1] = -3;
 $figs[0][53][2] = 3;
 $figs[0][54] = array();
 $figs[0][54][1] = -4;
 $figs[0][54][2] = 2;
 $figs[0][55] = array();
 $figs[0][55][1] = -5;
 $figs[0][55][2] = 1;
 $figs[0][56] = array();
 $figs[0][56][1] = -5;
 $figs[0][56][2] = 0;
 $figs[0][57] = array();
 $figs[0][57][1] = -4;
 $figs[0][57][2] = -1;
 $figs[0][58] = array();
 $figs[0][58][1] = -3;
 $figs[0][58][2] = -2;
 $figs[0][59] = array();
 $figs[0][59][1] = -2;
 $figs[0][59][2] = -3;
 //DEV boucles pour gagner du temps
 $car4 = 0;
 while($car4 < 10) //zone bleue
 {
  $car4++;
  $figs[0][$car4][0] = 4;
 }
 $car3 = 11;
 while($car3 < 22) // zone rouge
 {
  $car3++;
  $figs[0][$car3][0] = 3;
 }
 $car2 = 23;
 while($car2 < 38) //zone jaune
 {
  $car2++;
  $figs[0][$car2][0] = 2;
 }
 $car1 = 39;
 while($car1 < 59) //zone verte
 {
  $car1++;
  $figs[0][$car1][0] = 1;
 }
 //SUITE DEV FINIR ZONES
 
 $ndf--;
 $sql1 = mysql_query("SELECT count(*) FROM map");
 $sql2 = mysql_result($sql1, 0, 0);
 $nbact = floor(($sql2 / 60) /1.3 );
 $curseur = 0;
 $arid = array();
 $caid = -1;
 while($nbact > $curseur)
 {
  $rdf = rand(0, $ndf);
  $sql3 = mysql_query("SELECT x, y FROM meteo ORDER BY rand() LIMIT 1");
  $sql4 = mysql_fetch_array($sql3);
  $c2 = -1;
  $rtemps = rand(0, 3);
  if($rtemps == 0) { $temps = 'brouillard'; }
  if($rtemps == 1) { $temps = 'neige'; }
  if($rtemps == 2) { $temps = 'pluie'; }
  if($rtemps == 3) { $temps = 'pluie'; }
  while($c2 < 59)
  {
   $c2++;
   $xf = $sql4['x'] + $figs[$rdf][$c2][1];
   $yf = $sql4['y'] + $figs[$rdf][$c2][2];
   mysql_query("UPDATE meteo SET temps = '".$temps."', level = '".$figs[$rdf][$c2][0]."' WHERE y = '".$yf."' AND x = '".$xf."'");
   $asql1 = mysql_query("SELECT id FROM meteo WHERE y = '".$yf."' AND x = '".$xf."'");
   $asql2 = mysql_fetch_array($asql1);
   $caid++;
   $arid[$caid] = $asql2['id'];
  }
  $curseur++;
 }
 $where = array();
 $bsql1 = mysql_query("SELECT id FROM meteo");
 while($bsql2 = mysql_fetch_array($bsql1))
 {
  $c3 = -1;
  $verrif = 0;
  while($c3 < $caid)
  {
   $c3++;
   if($arid[$c3] == $bsql2['id'])
   {
    $verrif = 1;
   }
  }
  if($verrif == 0)
  {
   $where[] = $bsql2['id'];
  }
 }
 $query = "UPDATE meteo SET temps = 'beau', level = '0' WHERE id IN (".implode(",", $where).")";
 mysql_query($query);
 mysql_query("UPDATE meteo SET temps = 'beau', level = '0' WHERE temps = 'null'");
}

Posté : 27 avr. 2007, 14:51
par sadeq
Sadeq => Merci de ta proposition mais malheursement je ne pourrait pas l'appliquer à mon cas, car je crois ta solution implique que les id se suivent ce qui n'est pas mon cas (on va s'occuper du 4 puis du 30 même s'i ly en a 25 autres entre eux ou même s'il y en a 23 autres et 2 qui ont été supprimés...)
Excuses moi, mais ce n'est pas "ma solution" mais c'est "ta solution" c'est toi qui mets une boucle d'Update de 0 à 100 pas moi.
Moi je ne fais que reprendre ton code et l'optimiser puisqu'aucune règle de gestion n'a été expliqué.

Posté : 27 avr. 2007, 14:54
par naholyr
Excuses moi, mais ce n'est pas "ma solution" mais c'est "ta solution" c'est toi qui mets une boucle d'Update de 0 à 100 pas moi.
Moi je ne fais que reprendre ton code et l'optimiser puisqu'aucune règle de gestion n'a été expliqué.
Non lui il fait des boucles plus compliquées que ça. C'est dans mes exemples que j'ai utilisé de simples boucles de 0 à 100, pour illustrer.

Posté : 27 avr. 2007, 15:08
par cicom
Sadeq => Je suis désolé mais regarde mon script (post précédent que j'ai fait) et dit moi si t'arrives à appliquer la solution que tu me proposes quelque part, après tout tu la matrises mieux que moi puisque c'est toi qui la propose, et si t'as besoin d'infos pour comprendre mon script poses en autant de questions que tu veux je me ferai un plaisir d'y répondre.

Sinon je suis toujours prenneur pour l'explication des index unique, car je pense Naholyr avoir respecté ce qui était en gras dans ta solution, mais après j'ai peut être compris de travers ce qu'est un index unique, si tu puovais m'expliquer ce serait simpa!
Merci à tous!

Posté : 27 avr. 2007, 16:33
par sadeq
Désolé, en proposant la simplif de la solution de Naholyr j'ai confondu avec toi. c'est pas grave :oops:

Quant à ton script (et là je reprend ton dernier) j'ai compris du moins pour sa dernière partie que tu mémorise des id que tu souhaite exclure l'ors de ton dernier Update.

J'ai une proposition de simplification qui élimine la boucle de vérif: En effet au lieu de faire un SELECT de tous les id pour entammer une recherche des id non préalablement sélectionnés dans $arid,
il suffit de lancer directement l'Update des id NOT IN $arid. Ce qui donne un truc comme ça :
$query = "UPDATE meteo SET temps = 'beau', level = '0' WHERE id NOT IN (".implode(",", $arid).")";
En remplacement du bloc :
$where = array(); 
 $bsql1 = mysql_query("SELECT id FROM meteo"); 
 while($bsql2 = mysql_fetch_array($bsql1)) 
 { 
  $c3 = -1; 
  $verrif = 0; 
  while($c3 < $caid) 
  { 
   $c3++; 
   if($arid[$c3] == $bsql2['id']) 
   { 
    $verrif = 1; 
   } 
  } 
  if($verrif == 0) 
  { 
   $where[] = $bsql2['id']; 
  } 
 } 
 $query = "UPDATE meteo SET temps = 'beau', level = '0' WHERE id IN (".implode(",", $where).")";