Optimisation code de recherche

saojin 11 Messages postés vendredi 9 juillet 2004Date d'inscription 28 août 2006 Dernière intervention - 25 août 2006 à 16:39 - Dernière réponse : saojin 11 Messages postés vendredi 9 juillet 2004Date d'inscription 28 août 2006 Dernière intervention
- 28 août 2006 à 14:25
Bonjour, j'ai fais un p'tit module de recherche pour un site et j'aurais aimé avoir des conseils pour l'optimiser ou savoir si je devrai changer completement mon algo.
si vous pouver m'aider ce serait super
<hr />$donnee= explode(" ",$_POST['champ']);
$nbr_mot=count($donnee);
 for ($c=0; $c < $nbr_mot; $c++){
// echo $donnee[$c]."   ";
 $produit = new scope("SELECT * FROM produit where mot_cle like '%".$donnee[$c]."%' and visible='1'");
 while ($val=$produit->suivant())
   {
   $existe=0;
   $indexMax=count($designation);
   for($I=0;$I<$indexMax;$I++){ // si oui on rajoute les produits a ceux qui existait deja
    if($designation[$I][0]==$produit->champ('id_produit')){
     $designation[$I][1]+=1;
     $existe=1;
   }   
   }
   if ($existe==0){
   $designation[$indexMax][0]=$produit->champ('id_produit');
   $designation[$indexMax][1]=1;
   
  
 }
   }
   
//
 $produit = new scope("SELECT * FROM textile where mot_cle like '%".$donnee[$c]."%' and visible='1'");
 while ($val=$produit->suivant())
   {
   $existe=0;
   $indexMax=count($designation);
   for($I=0;$I<$indexMax;$I++){ // si oui on rajoute les produits a ceux qui existait deja
    if($designation[$I][2]==$produit->champ('id_textile')){
     $designation[$I][1]+=1;
     $existe=1;
    }
   }
   if ($existe==0){
   $designation[$indexMax][2]=$produit->champ('id_textile');
   $designation[$indexMax][1]=1;
   
  
 }
   }
 }  
 //-----------------------------------------------------------------------------------------------------------------
 // classement du tableau
 //-----------------------------------------------------------------------------------------------------------------
   if (count($designation)!=0){
   //classement  decroissant
    for($I=0;$I<count($designation)-1;$I++){
      for($J=$I+1;$J<count($designation);$J++){
    if ($designation[$I][1]<$designation[$J][1]){
     $temp2=$designation[$I][2];
     $temp1=$designation[$I][1];
     $temp0=$designation[$I][0];
     $designation[$I][2] = $designation[$J][2];
     $designation[$I][1] = $designation[$J][1];
     $designation[$I][0] = $designation[$J][0];
     $designation[$J][2] = $temp2;
     $designation[$J][1] = $temp1;
     $designation[$J][0] = $temp0;
    }
      }
     }
   }
  
 $nbraffichage=count($designation);
/* ajout des information dont on aura besoin pour l'affichage
 0->id_produit
 1->ordre d'importance
 2->id_textile
 3->designation
 4->prix de depart
 5->promotion
 6->nouveautes
 7->image
 8->href
 9->express
 10->id
 */
$date_jour=gmdate("Y-m-d");
//echo $nbraffichage;
for($I=0;$I<$nbraffichage;$I++){
//Produits:
if ($designation[$I][0]!=""){
  $id_produit=$designation[$I][0];
  //requete produit
  $produit= new scope("select designation,fin_news,visible,express from produit where visible='1' and id_produit='".$id_produit."' limit 0,1");
  $produit->suivant();
  //remplissage info produit
  $designation[$I][10]=$id_produit;
  $designation[$I][3]=$produit->champ('designation');
  if (date_jour<=$produit->champ('fin_news'))
   $designation[$I][6]="new";
  if ($produit->champ('fin_news')=='1')
   $designation[$I][9]="express";
  //requete tarif
   $tarif= new scope("select min(tarif) mintarif from tarif where id_produit='".$id_produit."' group by id_produit");
      $val=$tarif->suivant();
   $designation[$I][4]=$tarif->champ('mintarif');
  //existence promotion ?
  $promotion= new scope("select id_promotion from promotion where date_debut <= '".$date_jour."' and date_fin >= '".$date_jour."' and id_produit='".$id_produit."' limit 0,1" );
   if($promotion->suivant()){
   $designation[$I][5]="promo";
   $tarif= new scope("select min(tarif) mintarif ,id_promo  from tarifpromo where id_promo='".$promotion->champ('id_promotion')."' group by id_promo");
      $val=$tarif->suivant();
   $designation[$I][4]=$tarif->champ('mintarif'); 
   }
  //image et liens
   $image="images/produits/photo".$id_produit."1.jpeg";
  
     if (!(file_exists($image))){
     $image="administration/include/image/default.jpg"; }
  $designation[$I][7]=$image;
  $designation[$I][8]="details-produits.php?key=".$id_produit;
  
  }
//Textile:
 elseif($designation[$I][2]!=""){
  //info textile
  $id_textile=$designation[$I][2];
  $textile= new scope("select designation,tarif from textile where visible='1' and id_textile='".$id_textile."' limit 0,1");
  $textile->suivant();
  $designation[$I][10]=$id_textile;
  $designation[$I][3]=$textile->champ('designation');
  $designation[$I][4]=$textile->champ('tarif');
  if (date_jour<=$textile->champ('fin_news'))
   $designation[$I][6]="new";
  //existence promotion ?
  $promotion= new scope("select tarif_textile from promotion where date_debut <= '".$date_jour."' and date_fin >= '".$date_jour."' and id_textile='".$id_textile."' limit 0,1" );
  
   if($promotion->suivant()){
   $designation[$I][5]="promo";
   $designation[$I][4]=$promotion->champ('tarif_textile'); 
   }
   //image et liens
  
     $image="images/textile/photo".$id_textile."1.jpeg";
     if (!(file_exists($image)))
     $image="administration/include/image/default.jpg";
   
  $designation[$I][7]=$image;
  $designation[$I][8]="details-textile.php?key=".$id_textile;
 
 }
 

}

<hr />
Je fais des recherche sur deux table differentes produit et textiles (pour des besoins pour le reste du site ). Mon souci est que lorsque ma table contient ses 8 000 enregistrement , ça commencent a prendre beacoup de temps pour repondre.

Merci d'avance
<hr />
stephane
La vie n'est qu'un long fleuve d'apprentisssage
Afficher la suite 

Votre réponse

6 réponses

malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 25 août 2006 à 17:50
0
Utile
Hello,

ton code est un peu long pour le détailler...
déjà, évite les SELECT * qui tue rapidement un serveur de bdd...
BETWEEN est sûrement plus optimisé que date <= and date >=
Ensuite apparemment la classe que tu appelles utilises des row_seek, ce qui est assez lent, mais pourquoi pas...les curseurs sont pratiques.
Il y a bcp de conditions...sont elles vraiment nécessaires ?  Pas de jointures possibles pour minimiser les données à aller chercher ?

Ca : elseif($designation[$I][2]!=""){
=> elsif (!empty ($designation[$I][2]))

visible='1'
=> si visible est un champ avec une valeur de type entier, les apostrophes sont inutiles (voire en trop). Et sinon...si tu n'as que des valeurs de type entier...change le type de ton champ!

Après bon...je ne sais pas, je n'ai pas le courage de tout décortiquer.
Commenter la réponse de malalam
saojin 11 Messages postés vendredi 9 juillet 2004Date d'inscription 28 août 2006 Dernière intervention - 25 août 2006 à 18:18
0
Utile
Merci , ça me permet deja d'avancer beaucoup et je t'en remercie.
 
J'ai oublie de mettre le code de ma classe , c vrai que ça aurait aidé. J'utilise  mysql_fetch_array dedans.
visible est efectivement de type entier puisqu'il ne prend ke 0 ou 1 , j'ai dc coriger l'erreur. Je retire de suite tous mes * afin d'ameliorer mes requetes.Dommage qu'on puissent pas editer les messages , j'aurais fais les correction en live.

Les conditions sont obligatoires par rapport a mes requetes par contre je vais travailler le fait de pouvoir ajouter des jointures si ça peut accelerer le traitement. Par contre mon souci est en fin de traitement recuperer les données une a une car en utilisant
select id_produit from table where  id_produit in (5, 6.1) ça me retourne 1 5 6 et je perd alors mon classement. Y ' a t'il une autre solution?
Commenter la réponse de saojin
malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 26 août 2006 à 12:37
0
Utile
Tu sais, en général, des requêtes prenant trop de temps sont dûes à une mauvaise structure de la base de données attaquée. Un petit tour sur les indispensables de la méthode Merise (bien moins complexe qu'il n'y parait) est une bonne idée pour se raffraîchir les idées sur la question.
Pour ta dernière question, je ne vois effectivement pas vraiment d'autres solutions...qu'un curseur (je ne sais pas si c'est ce que tu as mis en oeuvre : je parle de row_seek et compagnie).
mysql_fetch_array n'est une bonne idée que si on utilise avec ses options : MYSQL_ASSOC ou MYSQL_NUMERIC (je ne sais plus pour la dernière). Ou bien soit mysql_fetch_row ou mysql_fetch_assoc (). Car fetch_array renvoi un tableau double : indexé numériquement associativement. Ce qui est une perte de performance énorme, et de plus, totalement inutile.
Commenter la réponse de malalam
FhX 2368 Messages postés mercredi 13 octobre 2004Date d'inscription 18 avril 2015 Dernière intervention - 26 août 2006 à 20:11
0
Utile
MYSQL_BOTH :)

Bah vi Mala, soit l'un, soit l'autre, soit les 2 :D
Par defaut, c'est MYSQL_BOTH au passage ;)

Si c'est pour utiliser les curseurs, autant le faire via les itérateurs en PHP5. Mais au vu de ce que je vois, c'est du PHP4... donc dommage :/
Commenter la réponse de FhX
saojin 11 Messages postés vendredi 9 juillet 2004Date d'inscription 28 août 2006 Dernière intervention - 28 août 2006 à 14:20
0
Utile
Ben en fait non j'avais pas mis en place un curseur, je vais travailler cette idée. Pour l'instant je recupereais les enregistrements que je mettais dans un tableau. et je classais le tableau selon le nombre de mot clés retrouvés dans les mot recherchés. Par contre je vois pas a quoi me servirais les curseurs, mais je vais regarder p'tet que je ne connais pas toutes leur propriétés.

En tout cas merci de vous etre penchés sur mon cas.
Commenter la réponse de saojin
saojin 11 Messages postés vendredi 9 juillet 2004Date d'inscription 28 août 2006 Dernière intervention - 28 août 2006 à 14:25
0
Utile
Concernant les requete un peu complexes , c'est du au fait que j'ai beaucoup de table du a un gros nombres de paramètre et de types de produit completement different, leurs seul point commun : les mot clef, designatin mais ou ça devient assez complex c'est quand je dois recuperer le plus petit de touts leur tarif ( tarif different selon quantite) , selon l'existence ou non d'une promotion a la date d'aujourd'hui, selon le type de produit ( promotion et remise differentes) et selon qu'un client soit connecté ( remise supplémentaire ). La recherche est d'ailleur la seule fonction qui me demande des requete aussi complexe, le reste est plus facilement optimisable.

saojin
La vie n'est qu'un long fleuve d'apprentisssage
Commenter la réponse de saojin

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.