IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Optimisation de scripts PHP/MySQL [Débat]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    Citation Envoyé par XtofRoland
    ++i est legerement plus performant que i++ ;-)
    mais c'est du detail ;-)
    Ouaip, je confirme.

  2. #2
    Membre expérimenté
    Inscrit en
    Janvier 2004
    Messages
    242
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 242
    Par défaut
    Un truc tout bete d'optimisation, installer un cache du script compilé genre eaccelerator et les perfs seront grandement améliorée.

    Donc c'est bien d'optimiser a mort le code, faudrait aussi que ça soit le cas du coté du serveur

  3. #3
    Membre émérite
    Avatar de Kioob
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    550
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Par défaut
    Citation Envoyé par chaced
    Donc c'est bien d'optimiser a mort le code, faudrait aussi que ça soit le cas du coté du serveur
    yep, mais ça c'est bien souvent l'hebergeur qui le controle.

    Et puis sur un truc codé comme un goret, le cache d'OpCode ne changera pas grand chose : phpBB est lent qu'eAccelerator soit installé ou non.

  4. #4
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    Citation Envoyé par Kioob
    phpBB est lent qu'eAccelerator soit installé ou non.
    Troll spotted
    Sérieusement, heureusement que phpBB met en cache pas mal de trucs (ex. : nombre de posts par user), sans quoi ce serait encore plus lent (et pourtant, ce serait la "bonne" méthode à utiliser).
    Vivent les index ?

  5. #5
    Membre expérimenté
    Inscrit en
    Janvier 2004
    Messages
    242
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 242
    Par défaut
    Citation Envoyé par Kioob
    Citation Envoyé par chaced
    Donc c'est bien d'optimiser a mort le code, faudrait aussi que ça soit le cas du coté du serveur
    yep, mais ça c'est bien souvent l'hebergeur qui le controle.

    Et puis sur un truc codé comme un goret, le cache d'OpCode ne changera pas grand chose : phpBB est lent qu'eAccelerator soit installé ou non.
    Je sens un bon gain en perf, mais j'ai un forum Skyomatic, pas de phpbb

  6. #6
    Membre chevronné Avatar de XtofRoland
    Profil pro
    Inscrit en
    Août 2005
    Messages
    357
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2005
    Messages : 357
    Par défaut Re: Optimisation de scripts Php/MySQL
    Citation Envoyé par ermelir
    Citation Envoyé par DgG
    A vous maintenant de donner vos astuces, ou de poser des questions.
    - je rajouterais unset($objet) lorsque l'on utilise des objets
    - j'ai aussi pu constater que pour des requetes compliquées le fait de liberer le resultset accelerait considerablement le script , la toujours avec unset
    Il me semble qu'un objet est libéré automatiquement a sa derniere utilisation...

  7. #7
    Membre chevronné
    Homme Profil pro
    /
    Inscrit en
    Février 2003
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : /

    Informations forums :
    Inscription : Février 2003
    Messages : 434
    Par défaut
    Une optimisation qui peut également apporter d'énorme gain de temps d'exéctution lors de nombreuses requetes de selection dans une base de donnée et la mise en cache des résultats dans un fichier local. Le gain n'est évidemment sensible que si les données sélectionnées évoluent peu au cours du temps. Cette astuce dans sa forme actuelle est toutefois à employer avec précaution car tant que le fichier cache n'aura pas été supprimer, cela masquera les données réellement présentes dans la base.
    Dans mon cas, il s'agit d'une gallerie photo. Si elle est mise à jour toutes les semaines c'est énhooooorme .
    Pour mesurer l'ecart de performences, j'ai utilisé le bench fourni par iubito et effectué 5000 itérations
    Voici les résultats que j'ai obtenu
    Requete simple sur deux tables simultanées
    SELECT a.id, a.filename, a.title, a.author, a.description, a.added, b.folder FROM MySite_pictures a,MySite_albums b WHERE (a.idalbum=55 AND b.id=55) LIMIT 0,9
    Durée: 11.16851 s, Vitesse: 448 requetes par seconde
    Requete simple sur deux tables simultanées, cache active
    SELECT a.id, a.filename, a.title, a.author, a.description, a.added, b.folder FROM MySite_pictures a,MySite_albums b WHERE (a.idalbum=55 AND b.id=55) LIMIT 0,9
    Durée: 1.48137 s, Vitesse: 3375 requetes par seconde
    Requete AVEC JOIN
    SELECT a.id, a.filename, a.title, a.author, a.description, a.added, b.folder FROM MySite_pictures a, MySite_albums b JOIN MySite_albums ON a.idalbum=b.id WHERE a.idalbum=55 LIMIT 0,9
    Durée: 13.16669 s, Vitesse: 380 requetes par seconde
    Requete AVEC JOIN et cache
    SELECT a.id, a.filename, a.title, a.author, a.description, a.added, b.folder FROM MySite_pictures a, MySite_albums b JOIN MySite_albums ON a.idalbum=b.id WHERE a.idalbum=55 LIMIT 0,9
    Durée: 1.30094 s, Vitesse: 3843 requetes par seconde
    La différence est phénoménale dans mon cas, ca va entre 8 et 9 fois plus vite

    Voici le code que j'ai utilisé, pour ceux que ca interesse. Il n'a subit aucune optimisation particulière; il devrait donc être encore possible d'améliorer le résultat.

    Code de Test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    	echo '<h2>Requete simple sur deux tables simultanées</h2>';
    	$SQL = "SELECT a.id, a.filename, a.title, a.author, a.description, a.added, b.folder 
    			FROM $Table_Pictures a,$Table_Albums b WHERE (a.idalbum=$Album_ID AND b.id=$Album_ID) LIMIT $FirstPic,$galPicturesPerPage";
    	echo $SQL.'<br>';
    	start();
    	for ($i=0; $i<5000; $i++){
    	$myPictures = $myDB->Query($SQL);
    	};
    	stop();
    	echo resultat(5000, 'requetes');
     
    	echo '<h2>Requete simple sur deux tables simultanées, cache active</h2>';
    	$SQL = "SELECT a.id, a.filename, a.title, a.author, a.description, a.added, b.folder 
    			FROM $Table_Pictures a,$Table_Albums b WHERE (a.idalbum=$Album_ID AND b.id=$Album_ID) LIMIT $FirstPic,$galPicturesPerPage";
    	echo $SQL.'<br>';
    	start();
    	for ($i=0; $i<5000; $i++){
    	$myPictures = $myDB->Query($SQL, true);
    	};
    	stop();
    	echo resultat(5000, 'requetes');
    (Il y a la même chose avec la deuxieme requête)

    La suite, le code de ma classe qui effectue la requete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    	 /**********************************************************************
    	 *	Generic SQL query.
    	 ***********************************************************************
    	 *	@param $query  	
    	 *	@retrun : 
    	 **********************************************************************/				
    		function Query($query, $Cache = false){
    			//Create the name of the file wich could contain the values
    			$filename = $_SERVER['DOCUMENT_ROOT'].'/cache/'.md5($query).'.txt';
    			if (!(strpos($query, 'SELECT') === false) && ($Cache == true) && file_exists($filename) && is_readable($filename)){
    				$result = array();
    				$result = $this->LoadArrayFromFile($result, $filename);
    				return $result;
    			} else {		
    				//If there's no existing connection to the server, 
    				//let's try to create one.
    				if (!$this->dbConnected){ $this->Connect();};
    				//If there's a connection to the server and if we can acces the 
    				//database we can execute our query
    				if ($this->dbConnected && $this->OpenDataBase()){
    					//Construct the query
    					$myQuery = $query;
    					$this->LastQuery  = $myQuery;				
    					if ($res = mysql_query($myQuery)){
    						$result = array();
    						$i = 0;
    						while ($data = mysql_fetch_row($res)){
    							$j = 0;
    							foreach ($data as $item){
    								$result[$i][mysql_field_name($res,$j)] =  $data[$j];
    								$j++;
    							}
    							$i++;
    						};			
    						if (!(strpos($query, 'SELECT') === false) && ($Cache = true)){
    							//Store the result in the file for the next time 
    							$this->SaveArrayToFile($result, $filename);
    						};		
    						return $result;
    					} else {
    						$this->errorMessage = '<i>'.$myQuery.'</i><br/>'.mysql_error();
    						$this->errorNumber = mysql_errno();
    						if ($this->Debug){	$this->GetLastError();};							
    					};
    				};
    			};
    		}
    ET enfin, les deux procedures que j'ai écrite pour stocker mes array dans des fichiers et les recharger par après
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    	 /**********************************************************************
    	 *	Save an array in a text file. An implicit conversion from each item
    	 *	in the array to string must be possible otherwise it shouldn't work.
    	 *	The array may contain arrays but those cannot.
    	 ***********************************************************************
    	 *	@param &$array : pointer to the array to store
    	 *	@param $filename : name of the file where the value must be saved	
    	 *	@retrun : /
    	 **********************************************************************/			
    		function SaveArrayToFile(&$array, $filename){
    			$Header = implode(', ',array_keys($array[0]))."\r\n";
    			$Content = '';
    			foreach ($array as $item){
    				//Pour chaque photo
    				$Content .= implode(', ',$item)."\r\n";				
    			};
    			$handle = fopen($filename, "w+");
    			fwrite($handle, $Header.$Content);
    			fclose($handle);	
    		}
     
    	 /**********************************************************************
    	 *	Load an array form a text file. An implicit conversion from string 
    	 *	to the original type must be possible otherwise it shouldn't work.
    	 ***********************************************************************
    	 *	@param $filename : name of the file where the value has been saved	
    	 *	@retrun : loaded array
    	 **********************************************************************/					
    		function LoadArrayFromFile($filename){
    			$handle = fopen($filename, "r");
    			$Text = fread($handle, filesize($filename));
    			fclose($handle);	
    			$Content = explode("\r\n", $Text);
    			//Recuperer les index des champs
    			$i = 0;
    			foreach(explode(", ", $Content[0]) as $item){
    				$Keys[$i] = $item;
    				$i++;
    			};
    			$Text_Count = count($Text);
    			for($i=1; $i<$Text_Count; $i++){
    				$j = 0;
    				foreach(explode(", ", $Content[$i]) as $item){
    					$array[$i-1][$Keys[$j]] = $item;
    					$j++;
    				};
    			};
    		}			
     
    	};
    En modifiant ces deux dernières fonctions pour sérializer/desérialiser le tableau, on perd un peu en performance mais on gagne en souplesse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    	 /**********************************************************************
    	 *	Save an array in a text file. 
    	 ***********************************************************************
    	 *	@param &$array : pointer to the array to store
    	 *	@param $filename : name of the file where the value must be saved	
    	 *	@retrun : /
    	 **********************************************************************/			
    		function SaveArrayToFile(&$array, $filename){
    			$handle = fopen($filename, "w+");
    			fwrite($handle, serialize($array));	//fwrite($handle, $Header.$Content);
    			fclose($handle);	
    		}
     
    	 /**********************************************************************
    	 *	Load an array form a text file. 
    	 ***********************************************************************
    	 *	@param $filename : name of the file where the value has been saved	
    	 *	@retrun : loadded array
    	 **********************************************************************/					
    		function LoadArrayFromFile($filename){
    			$handle = fopen($filename, "r");
    			$Text = fread($handle, filesize($filename));
    			fclose($handle);	
    			$array = unserialize($Text);
    		}			
    	};
    Requete simple sur deux tables simultanées
    SELECT a.id, a.filename, a.title, a.author, a.description, a.added, b.folder FROM MySite_pictures a,MySite_albums b WHERE (a.idalbum=55 AND b.id=55) LIMIT 0,9
    Durée: 11.7862 s, Vitesse: 424 requetes par seconde
    Requete simple sur deux tables simultanées, cache active
    SELECT a.id, a.filename, a.title, a.author, a.description, a.added, b.folder FROM MySite_pictures a,MySite_albums b WHERE (a.idalbum=55 AND b.id=55) LIMIT 0,9
    Durée: 1.48182 s, Vitesse: 3374 requetes par seconde
    Requete AVEC JOIN
    SELECT a.id, a.filename, a.title, a.author, a.description, a.added, b.folder FROM MySite_pictures a, MySite_albums b JOIN MySite_albums ON a.idalbum=b.id WHERE a.idalbum=55 LIMIT 0,9
    Durée: 13.24316 s, Vitesse: 378 requetes par seconde
    Requete AVEC JOIN et cache
    SELECT a.id, a.filename, a.title, a.author, a.description, a.added, b.folder FROM MySite_pictures a, MySite_albums b JOIN MySite_albums ON a.idalbum=b.id WHERE a.idalbum=55 LIMIT 0,9
    Durée: 1.51247 s, Vitesse: 3306 requetes par seconde

  8. #8
    Invité de passage
    Inscrit en
    Juin 2009
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 1
    Par défaut
    bonjour: svp mon français est trop faible mais j'essaye de m'exprimer pour mieux poser ma question .
    dans un forum ou chat on trouve généralement une zone de texte je veux copier coller
    dans cette zone une application visual basic et dans cette application un bouton si on clic sur ce bouton un texte apparait. b1 sur ce texte est préalablement programmer dans l'application par l'utilisateur de application et pas par l'utilisateur du chat ou du forum ,j'espère que c'est clair merci de votre compréhension .

  9. #9
    Membre chevronné
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Citation Envoyé par alekusu
    Dans le cas d'un magazine en ligne, où on aurait par exemple une quinzaine de requete SQL SELECT pour afficher différents éléments sur la home, ne serait-ce pas plus malin de :

    1/ Créer une table pour la home, où dynamiquement à chaque modification coté back office, ça update cette table qui contient uniquement les éléments à afficher sur la home

    2/ Appeler avec une seule requete SQL SELECT tout le contenu de cette table et afficher son contenu au fur et à mesure de la page.

    J'ai jamais lu ce genre de proposition qui en plus de faire des tables par type de données fait aussi des tables par page.

    Vous pensez que dans le cas de sql select c'est une solution pertinente ?
    Cette approche bien qu'elle soit juste dans l'intention n'est pas bonne du tout dans la forme, car c'est ainsi que fonctionnent la plupart des CMS et qui dans le cas présent constiste à utiliser la BD pour faire de la persistance de classe ce qui est à proscrire dans un contexte où les performances et la disponibilité en charge doivent être garantis.

    Dans le cas d'un site ecommerce il faut que la BD soit fortement normalisée et par conséquent qu'elle intègre les spécificités métier et fonctionnelles de l'applicatif Web.

    Pour ce qui est de l'affichage, appliquer votre vision est la bonne méthode à ceci près qu'il faille le faire avec des vues, bien qu'avec MySQL des requêtes dédiées soient le plus souvent les plus appropriées.

    ++

  10. #10
    Membre chevronné
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Billets dans le blog
    4
    Par défaut
    Je rajoute un lien discuté très recemment qui concerne également ce topic
    http://www.developpez.net/forums/d12...njections-sql/

    ++

Discussions similaires

  1. [Débutant] Accélérer et optimiser ses scripts PHP
    Par Metallic-84s dans le forum Langage
    Réponses: 6
    Dernier message: 24/03/2006, 12h37
  2. [MySQL] [SGBD] Script PHP/MYSQL d'access FTP
    Par ChRom dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 09/01/2006, 01h52
  3. Réponses: 9
    Dernier message: 05/01/2006, 12h24
  4. Recherche Login Script PHP & MySQL
    Par whbh dans le forum SQL Procédural
    Réponses: 9
    Dernier message: 01/12/2005, 16h45
  5. [MySQL] [Script]Optimisation de scripts Php/MySQL (2)
    Par copy dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 27/08/2004, 08h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo