script BDD trop lourd et lent.
Posté : 15 août 2006, 06:05
Bonjour a tous et merci d'avance à ceux qui m'aideront.
Voici mon script php, qui recopie et traite des informations depuis cette table : http://s11.travian.fr/map.sql
J'explique un peu le fonctionnement de mon code.
La table x_world (voire lien ci dessus), contient des entrées de villages.
- Je recopie cette table dans une table nommée "data_joueurs" (ceci est trés rapide, pas de pb).
- Ensuite je calcule le nombre de villages que posséde un joueur en parcourant toutes les entrées dont l'id correspond au même joueur, et je l'écris bien sur, je met soit à jour les données du village, soit je crée une nouvelle ligne, si elle n'existe pas.
- Je calcule la progression en lisant cette fois depuis la table data_joueurs afin de voire si le village du joueur progresse, régresse ou stagne.
- Je décale le nombre de points du village d'une case, afin d'avoir un historique de son évolution sur 10 jours.
Voilà le soucis c'est que l'opération de comptage des villages est la plus longue, et comme je traite 20 bases à la fois, cela me prend prés de 4h en tout, avec un ordinateur trés bon (amd 64 3000+ 1Go DDR PC3200).
j'ai essayé d'alloué plus de ram à mysql, mais il prend tjrs 12mo en processus, j'ai pourtant mi 128m.
Je précise que j'utilise EASY PHP 1.8, MySQL4, et donc un OS XP SP2.
J'attend de vous des idées d'amélioration du code, afin de gagner sensiblement en temps d'éxécution.
ps : je précise que ces calculs sont fais afin de ne pas gêner les visiteurs de mon futur site, qui devront les faires à la demande...
Voici mon script php, qui recopie et traite des informations depuis cette table : http://s11.travian.fr/map.sql
J'explique un peu le fonctionnement de mon code.
La table x_world (voire lien ci dessus), contient des entrées de villages.
- Je recopie cette table dans une table nommée "data_joueurs" (ceci est trés rapide, pas de pb).
- Ensuite je calcule le nombre de villages que posséde un joueur en parcourant toutes les entrées dont l'id correspond au même joueur, et je l'écris bien sur, je met soit à jour les données du village, soit je crée une nouvelle ligne, si elle n'existe pas.
- Je calcule la progression en lisant cette fois depuis la table data_joueurs afin de voire si le village du joueur progresse, régresse ou stagne.
- Je décale le nombre de points du village d'une case, afin d'avoir un historique de son évolution sur 10 jours.
Voilà le soucis c'est que l'opération de comptage des villages est la plus longue, et comme je traite 20 bases à la fois, cela me prend prés de 4h en tout, avec un ordinateur trés bon (amd 64 3000+ 1Go DDR PC3200).
j'ai essayé d'alloué plus de ram à mysql, mais il prend tjrs 12mo en processus, j'ai pourtant mi 128m.
Je précise que j'utilise EASY PHP 1.8, MySQL4, et donc un OS XP SP2.
J'attend de vous des idées d'amélioration du code, afin de gagner sensiblement en temps d'éxécution.
ps : je précise que ces calculs sont fais afin de ne pas gêner les visiteurs de mon futur site, qui devront les faires à la demande...
<?php
/*##### Paramètres de la base de donnees #####*/
$host= "localhost"; //Hote
$user= "root"; //Nom de l'utilisateur
$pass= "xxxxx"; //Mot de passe pour acceder a la base de donnees
$nombreServeursFr=13;
$nombreServeursFr=$nombreServeursFr+1;
$nombreServeursCom=7;
$nombreServeursCom=$nombreServeursCom+1;
set_time_limit(20000); //en seconde 20min*60=1200s
/*##### Paramètres de la base de donnees #####*/
$b=0;
while($b!=2)
{
if($b==0){$pays="_fr";$nombreServeurs=$nombreServeursFr;}else{$pays="_com";$nombreServeurs=$nombreServeursCom;}
$b++;
$a=1;
while($a!=$nombreServeurs)
{
$base="travian_s"."$a"."$pays"; //Nom de la base de donnees
$a++;
///////////////////////////////////////////BOUCLE DU CODE/////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Verifie si on peut se connecter a la base sql
$connect=mysql_connect($host,$user,$pass) or die ("Impossible de se connecter");
mysql_select_db($base, $connect) or die ("Impossible de selectionner la base de donnees");
/*##### création des tables #####*/
$table="globalData"; //données globales
//echo "Table : $table ($base) en cours....";
$sql_create = "CREATE TABLE IF NOT EXISTS `$table` (id INT (10) not null AUTO_INCREMENT, villages VARCHAR (255) not null, joueurs VARCHAR (255) not null, date DATE NOT NULL default '0000-00-00', PRIMARY KEY (id))";
$req_create = mysql_db_query($base, $sql_create) or die(mysql_error());
//echo (" OK!<br>");
$table ="data_joueurs"; //données personnalisés
$sql_create = "CREATE TABLE IF NOT EXISTS `$table` (idJoueur INT (10) not null,
pseudo VARCHAR (255) not null,
classement INT (10) null,
evolClassement VARCHAR (255) null,
peuple INT (10) not null,
nomAlliance VARCHAR (255) not null,
idAlliance INT (10) not null,
idVillage INT (10) not null,
nombreVillage INT (10) null,
nomVillage VARCHAR (255) not null,
population INT (10) not null,
pop1 INT (10) null,
pop2 INT (10) null,
pop3 INT (10) null,
pop4 INT (10) null,
pop5 INT (10) null,
pop6 INT (10) null,
pop7 INT (10) null,
pop8 INT (10) null,
pop9 INT (10) null,
pop10 INT (10) null,
populationTotale INT (10) null,
popT1 INT (10) null,
popT2 INT (10) null,
popT3 INT (10) null,
popT4 INT (10) null,
popT5 INT (10) null,
popT6 INT (10) null,
popT7 INT (10) null,
popT8 INT (10) null,
popT9 INT (10) null,
popT10 INT (10) null,
coordX VARCHAR (255) not null,
coordY VARCHAR (255) not null,
date DATE NOT NULL default '0000-00-00',
PRIMARY KEY (idVillage))";
$req_create = mysql_db_query($base, $sql_create) or die(mysql_error());
/*##### fin création des tables #####*/
//########### TEMPORAIRE #################//
//$sql="TRUNCATE TABLE `data_joueurs`";
//mysql_db_query($base, $sql) or die(mysql_error());
//$sql="TRUNCATE TABLE `x_world`";
//mysql_db_query($base, $sql) or die(mysql_error());
//########### FIN TEMPORAIRE #################//
//#################################### A FAIRE ##############################################//
//------> Enregistre les != villages du meme joueurs dans la nouvelle table data_joueurs, ou la met a jour pour
//eviter les doublons.
$date=date("Y-m-d");
$updateEntries=0;
$newsEntries=0;
$result = mysql_query ("SELECT * FROM x_world") or die ("Impossible d'executer la requete 50");
while ($row = mysql_fetch_array($result)) {
//Joueur
$idJoueur = $row ["idJoueur"];
$pseudo= $row ["joueur"];
$peuple = $row ["peuple"];
//Ally
$nomAlliance = $row ["alliance"];
$idAlliance = $row ["idAlliance"];
//Village
$idVillage = $row ["idVillage"];
$nomVillage = $row ["Village"];
$population = $row ["population"];
$coordX = $row ["X"];
$coordY = $row ["Y"];
//---> nombre de villages du joueur et points de tous ses villages
$result02 = mysql_query ("SELECT idVillage, population FROM x_world WHERE idJoueur='$idJoueur'") or die ("Impossible d'executer la requete 56");
$nbVillagesJoueur = mysql_num_rows($result02);
$populationTotale=0;
while ($row03 = mysql_fetch_array($result02)) {
$popVillage = $row03 ["population"];
$populationTotale = $populationTotale+$popVillage;
}
//
// --------------------> Ecriture BDD Joueurs !! <---------------//
////////////// <------ Test existance du village
$result05=mysql_query ("SELECT * FROM data_joueurs WHERE idVillage='$idVillage'") or die ("Impossible d'executer la requete 137");
$row05 = mysql_fetch_array($result05);
$idVillageBase = $row05["idVillage"];
///////////// <------ Fin du test
//si inexistant alors créer
if($idVillageBase!="$idVillage"){
$query = mysql_query ("INSERT INTO data_joueurs (idJoueur,pseudo,classement,peuple,nomAlliance,idAlliance,idVillage,nombreVillage,nomVillage,population,populationTotale,coordX,coordY,date) values ('$idJoueur', '$pseudo', '$classement', '$peuple', '$nomAlliance', '$idAlliance', '$idVillage', '$nbVillagesJoueur', '$nomVillage', '$population', '$populationTotale', '$coordX', '$coordY', '$date')");
$newsEntries++;
}
//sinon on met à jour
else{
$query = mysql_query ("UPDATE data_joueurs SET nomAlliance='$nomAlliance', idAlliance='$idAlliance', nomVillage='$nomVillage', population='$population', populationTotale='$populationTotale', date='$date' WHERE id='$idVillage'");
$updateEntries++;
}
//
// ------------------> Fin Ecriture BDD Joueurs!! <--------------//
//
}
echo("<br>$newsEntries--> Nouvelles entrées");
echo("<br>$updateEntries --> Mises à jour");
echo "<br>Table : $table ($base) en cours.... OK!";
//---> classement du joueur
$classement=0;
$idJoueur=0;
$result = mysql_query ("SELECT * FROM data_joueurs ORDER BY populationTotale DESC") or die ("Impossible d'executer la requete 178");
while ($row = mysql_fetch_array($result)) {
$idJoueurTMP = $row ["idJoueur"];
$ok=0;
if($idJoueur!=$idJoueurTMP){
$classement++;
$ok=1;
}
//Joueur
$idVillage = $row ["idVillage"];
$idJoueur = $row ["idJoueur"];
$pseudo = $row ["pseudo"];
/*
//vérif
if(($classement<11)&($ok==1)){
echo("<br>$classement. $pseudo"); }
*/
//---> progression ou régréssion?
$result04=mysql_query ("SELECT * FROM data_joueurs WHERE idVillage='$idVillage'") or die ("Impossible d'executer la requete");
$row04 = mysql_fetch_array($result04);
$ClassementBase = $row04["classement"];
//conditions
if($classement>"$ClassementBase"){
$evolClassement="-"; //régresse
}
if($classement<"$ClassementBase"){
$evolClassement="+"; //progresse
}
if($classement=="$ClassementBase"){
$evolClassement="="; //stagne
}
//
//données historiques de tous les villages
$popT1 = $row04["populationTotale"];
$popT2 = $row04["popT1"];
$popT3 = $row04["popT2"];
$popT4 = $row04["popT3"];
$popT5 = $row04["popT4"];
$popT6 = $row04["popT5"];
$popT7 = $row04["popT6"];
$popT8 = $row04["popT7"];
$popT9 = $row04["popT8"];
$popT10 = $row04["popT9"];
//données historiques du village
$pop1 = $row04["population"];
$pop2 = $row04["pop1"];
$pop3 = $row04["pop2"];
$pop4 = $row04["pop3"];
$pop5 = $row04["pop4"];
$pop6 = $row04["pop5"];
$pop7 = $row04["pop6"];
$pop8 = $row04["pop7"];
$pop9 = $row04["pop8"];
$pop10 = $row04["pop9"];
$query = mysql_query ("UPDATE data_joueurs SET classement='$classement', evolClassement='$evolClassement', popT1='$popT1', popT2='$popT2', popT3='$popT3', popT4='$popT4', popT5='$popT5', popT6='$popT6', popT7='$popT7', popT8='$popT8', popT9='$popT9', popT10='$popT10', pop1='$pop1', pop2='$pop2', pop3='$pop3', pop4='$pop4', pop5='$pop5', pop6='$pop6', pop7='$pop7', pop8='$pop8', pop9='$pop9', pop10='$pop10' WHERE idVillage='$idVillage'");
//test delete
//$query = mysql_query ("UPDATE data_joueurs SET classement='' WHERE idVillage='$idVillage'");
}
//#################################### FIN DE "A FAIRE" ########################################//
/*
//------> Recupere le nombre de villages
$result = mysql_query ("SELECT * FROM data_joueurs") or die ("Impossible d'executer la requete 155");
$nbVillages = mysql_num_rows($result);
//------> Recupere le nombre de joueurs
$result = mysql_query ("SELECT * FROM data_joueurs ORDER BY populationTotale DESC") or die ("Impossible d'executer la requete 178");
while ($row = mysql_fetch_array($result)) {
$X = $row ["nombreVillage"];
$nbJoueurs=$nbJoueurs+($X/($X^2));
}
echo ("<br>nombre de joueurs: $nbJoueurs");
// --------------------> Ecriture BDD Données Globales !! <---------------//
$query = mysql_query ("insert into globaldata (villages, joueurs, date) values ('$nbVillages', '$nbJoueurs', '$date')");
// ------------------> Fin Ecriture BDD Données Globales !! <--------------//
*/
//affichage de vérification
//echo ("<br>$monde $pays ==> $nbVillages villages");
//echo (" base $monde $pays faite!");
//////////////////////////////////////////////
/////
$temps = microtime(); // Timestamp actuel + microsecondes
$temps = explode(' ', $temps); // Je sépare la chaine, les deux segments sont retournés dans un array $temps[]
$fin = $temps[1] + $temps[0]; // J'additionne ces deux temps pour avoir le timestamp en microseconde de fin d'execution..
$duree = round(($fin - $debut),6); // Je fais la soustraction des deux temps pour obtenir le temps d'execution.. (Ici arrondi à 6 chiffres après la virgule, vous pouvez modifier cette valeur..)
$dureeMinutes=$duree/60;
echo"</div><div id=footer>\n<br><center> page générée en ". $duree. "s ($dureeMinutes minutes)</div>";
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//vide la table pour la prochaine importation
$sql="TRUNCATE TABLE `x_world`";
mysql_db_query($base, $sql) or die(mysql_error());
}
}