[Optimisation PHP] Résultat de requête Oracle

SuperCed

Membre expert
Club iGen
20 Juin 2001
1 333
70
45
superced.rb38.eu
Un site a été fait par un de mes prédécesseurs.

Ce site est un peu lent. J'ai donc essayé d'identifier pourquoi le site n'était pas réactif.

Après quelques recherches, il semble que ce soit l'éxécution php qui pose problème. Ce site est en php, et il utilise une base Oracle. Les requêtes faites directement sur la bases semblent très correctes au niveau du temps d'éxécution. Je n'ai pas remarqué de problème particulier.

J'ai donc cherché un peu plus dans le code PHP en utilisant mktime() pour savoir quelles étaient les parties "critiques", et je me suis apperçu qu'il y avait des appels de requêtes très imbriquées.
Le développeur utilise un fichier "select.php" pour toutes ses requêtes select . Ce fichier est parfois appelé dans des boucles elle-même contenues dans d'autres boucles while.
Clairement, c'est d'ici que vient le problème. Evidemment, il y a de gros accès disques à chaque fois et la lenteur doit provenir de cette façon de procéder.

Le problème est qu'il faudrait retoucher toutes les pages php ou il y a des boucles imbriquées avec des requêtes à l'intérieur. Bien sur, je pense que je vais devoir faire ce travail un peu plus tard, mais j'aimerais déjà m'attarder sur ce fameux "select.php" qui est appelé presque partout.

En effet, si j'arrive à optimiser ce fichier, alors tout le site sera plus rapide.

Il s'agit d'un fichier qui fait une requête sql sur la base Oracle, et qui remet les données correctement dans un tableau.
Pour cela, il y a 2 boucles imbriquées. Je me demande donc s'il est possible d'optimiser ce traitement php au maximum afin d'accélérer tout le site.

Voici le fichier "select.php" :

Bloc de code:
<?php

//Il suffit de mette en commentaire error_reporting pour faire du
//dÈbogage - voir quand il n'y a aucun rÈsultat "NO DATA FOUND" par exemple.
error_reporting(0);

//CrÈe un tableau, un curseur, compte les colonnes,
//fait le fetch en insÈrant dans le tableau.
$results = array();
$ora_cur = ora_do($ora_conn, $sql);

if($ora_cur){
  	//Nombre de colonnes
  	$numCols = ora_numcols($ora_cur);
  	
	//Prends la premiËre ligne et la met dans le tableau
  	$row = array();
	//Parcours les colonnes de la requete
  	for($i=0; $i<$numCols; $i++){
    	$row[ora_columnname($ora_cur, $i)] = ora_getcolumn($ora_cur,$i);
  	}
  	array_push($results,$row);
  	// "Fetch" des lignes, une par une, en crÈant un tableau pour chaque ligne.
  	// Chaque tableau est insÈrÈ ? la suite du tableau $results.
	while(ora_fetch($ora_cur)){ // Pour chaque ligne
	    $row = array();
    	
		for($i=0; $i<$numCols; $i++){ // Chaque colonne
			$row[ora_columnname($ora_cur, $i)] = ora_getcolumn($ora_cur,$i);
    	}
    	array_push($results,$row);
  	}
}
// Le fameux error_reporting. Mettre en commentaire pour voir les NO_DATA_FOUND.
error_reporting(1);

//print_r($results) pour vÈrifier le contenu

?>

Si vous avez une idée pour l'optimisation de cette partie, je serai très intéressé. J'ai aussi une idée vague, mais je préfère avoir quelques avis supplémentaires de façon à ne pas passer à coté de quelque chose.

Merci d'avoir lu jusqu'ici :wink:
 
Euh, la base Oracle que tu utilises c'est pas une base Oracle 7, 8 ou 9 par hasard ? Si c'est le cas autant utiliser la "nouvelle" version de l'extension Oracle de PHP... Elle est nettement plus pratique avec les fonctions oci_fetch_array ou carrement ocifetchstatement.

Et généralement c'est bien plus rapide que les versions maison :D
 
Sinon, j'aurais plutot fait quelque chose comme ça :

Bloc de code:
<?php

	$results = array();
	$ora_cur = ora_do( $ora_conn, $sql );

	if($ora_cur)
	{
		$rows = array();
		
		// fetch chaque ligne dans un array associatif
		while( ora_fetch_into( $ora_cur, $rows, ORA_FETCHINTO_NULLS|ORA_FETCHINTO_ASSOC ) )
		{
			// ajoute l'array a la fin de l'array final
			// (c'est fait par copie, donc on a pas a s'embeter)
			$results[] = $rows;
		}
	}

?>
 
Merci beaucoup pour toutes ces réponses.

Je ne peux rien changer du coté Oracle, qu'il s'agisse de la base ou du client. Je ne peux pas non plus toucher aux extensions php.

Je dois donc me contenter d'optimiser le résultat des requêtes.

Merci pour ton optimisation, elle est peut-être déjà plus rapide.
Je vais tester ça...
 
Ok, je me mets la dessus aujourd'hui et je teste ton code.

Dis moi, comment puis-je faire pour détecter les versions d'Oracle et pour voir quelles sont les extensions PHP présentes? Est-ce que le phpinfo() me donnera tout ça?

Merci beaucoup pour ton aide!
 
J'ai testé ça :

Bloc de code:
$results = array();
        $ora_cur = ora_do( $ora_conn, $sql );

        if($ora_cur)
        {
                //Nombre de colonnes
  	         $numCols = ora_numcols($ora_cur);
  	
	           //Prends la premiËre ligne et la met dans le tableau
  	         $row = array();
	           //Parcours les colonnes de la requete
  	         for($i=0; $i<$numCols; $i++){
    	           $row[ora_columnname($ora_cur, $i)] = ora_getcolumn($ora_cur,$i);
  	         }
  	         array_push($results,$row);
  	
                $rows = array();
                
                // fetch chaque ligne dans un array associatif
                while( ora_fetch_into( $ora_cur, $rows, ORA_FETCHINTO_NULLS|ORA_FETCHINTO_ASSOC ) )
                {
                        // ajoute l'array a la fin de l'array final
                        // (c'est fait par copie, donc on a pas a s'embeter)
                        $results[] = $rows;
                }
        }

Et après quelques tests, ça n'a pas l'air plus rapide. Dommage...

Si tu as une idée pour connaitre les versions dispos des clients Oracle, ça m'intéresse.
 
Pour voir si l'extension Oracle 8 marche sur ton serveur, essaye de lancer une fonction prefixée oci (tout est la... sinon fait un phpinfo(). Ça devrait s'afficher si c'est installé.

Sinon, pourquoi traites tu la premiere ligne a part ? en théorie tu ne devrais pas en avoir besoin...

@+

Guillaume
 
Si je ne le fait pas, les pages ne ofctionnent plus...
Donc j'ai remis cette première ligne dans un soucis de compatibilité.

Sinon, mon test n'est en fait pas très concluant en y réfléchissant bien.
Je vais donc garder ta méthode.

phpinfo me dit juste que Oracle est activé...
 
J'ai fait un test avec oci, mais ça ne fonctionne pas.
Je prends donc ta solution.

Puis, par le suite, il faudra que j'optimise page par page le php lui même.
 
Bon courage ! L'ancien developpeur a l'air de coder à la barbare :D Tu vas avoir du boulot ... (ça me fait penser qu'il faut que je mette a jour toutes mes classes de la MGZ ... c'etait pas mal pour mon premier site php, mais avec le recul et quelques sites dans les pattes, p't1 que c'est mauvais :D).
 
Ca dépend lequel!!! ;)

Il y en a eu 2, un qui a commencé vraiment à la barbare, et l'autre qui l'a été beaucoup moins mais qui ne s'est pas soucié de l'optimisation.