requete sur deux tables à optimiser

requete sur deux tables à optimiser - SQL/NoSQL - Programmation

Marsh Posté le 16-01-2006 à 13:18:28    

bonjour,
 
je cherche à optimiser une requete sur deux tables :
 
1 . table manif ; table qui stocke des événements avec un champs ville "renseigné par le nom de la ville"  pour chaque événement
2. table villes : table qui stocke les villes de plusieurs régions  et pour chaque ville champs "pays/territoire"
 
 
 
si je fais  
 
$sql = "SELECT DISTINCT * FROM manif LEFT JOIN villes ON villes.nom_ville=manifestation.manifestation_ville ";
$sql .="WHERE (manifestation_date_debut >='2006/01/16' OR manifestation_date_fin >='2006/01/16') AND villes.ref_pays='3'";  
 
çà marche mais çà mouline .. car il doit comparer avec tous les noms de villes (5000)  
 
 
j'ai essayé de faire une pré requete sur la table villes pour extraire les villes concernéés par la reference pays :  
 
 
$sql = "SELECT nom_ville FROM villes ";
  $sql .= "WHERE ref_pays = ".$pays;
 
  $rs = mysql_query($sql);
  $villes_ok = array() ;  
   while ($rsc=mysql_fetch_object($rs))  
    {  
    $villes_ok[] = $rsc->nom_ville;  
 
    }  
 
et ensuite :  
 
$sql = "SELECT DISTINCT ".$liste_champs." FROM manif,villes WHERE (manifestation_date_debut >='2006/01/16' OR manifestation_date_fin >='2006/01/16') ";
$sql = "AND ".in_array(manifestation.manifestation_ville, $villes_ok)."";
 
mais .. çà marche pas !  
 
si vous avez une idée pour améliorer çà  
merci

Reply

Marsh Posté le 16-01-2006 à 13:18:28   

Reply

Marsh Posté le 16-01-2006 à 13:40:27    

Code :
  1. SELECT DISTINCT *
  2. FROM manif LEFT JOIN villes ON villes.nom_ville=manifestation.manifestation_ville
  3. WHERE (manifestation_date_debut >='2006/01/16' OR manifestation_date_fin >='2006/01/16')
  4. AND villes.ref_pays='3'


 
nom_ville est un libellé. Ne pas utiliser ca pour faire une jointure. Privilegier un champ numerique.  
Y'a des index à mettre. J'opterai pour un index sur (identifiant_ville, ref_pays), identifiant_ville etant le champ numerique dit juste au dessus. Un autre index sur (manifestation_date_debut, manifestation_date_fin) pourrait aider.
 
Mais une jointure avec 5000 lignes est normalement immediate.


---------------
MZP est de retour
Reply

Marsh Posté le 16-01-2006 à 14:11:35    

oui ok pour les index  
mais manifestation.manifestation_ville est un libellé et je ne peux donc le comparer qu'avec un autre libellé nom_ville non ?

Reply

Marsh Posté le 16-01-2006 à 14:29:55    

et si tu changes le libellé d'une ville? Un libellé est une information par une clé-identifiant.
 
Je te conseille donc d'associer une clé (numerique) à un libellé, et de faire tes liens sur cette clé. Donc tu renseignes plutot la clé dans la table des manifestations que le libellé. Comme çà, une modification du libellé, n'impacte pas les autres tables. Et un index sur un numerique est plus leger et beaucoup plus efficace. ;)


---------------
MZP est de retour
Reply

Marsh Posté le 16-01-2006 à 14:38:41    

oui oui bien sur entièrement d'accord sauf que c'est pour implanter sur un système existant déjà avec des milliers de manifs de déjà rentrées !
 
je dois donc faire avec l'existant
mais le in_array c'était pas un bonne idée ?  
plutto que de comparer chaque manif_ville avec toutes lesvilles il ne comparerait qu'avec les villes déjà sélectionnées dans la premiière requete .. mais j'ai jamais vu in_array dns une requete !
une idée ?

Reply

Marsh Posté le 16-01-2006 à 14:41:33    

quel est l'interet? C'est beaucoup plus efficace une bonne requete avec index. MySql est plus efficace que PHP pour ce genre de trt


---------------
MZP est de retour
Reply

Marsh Posté le 16-01-2006 à 14:46:12    

ok oui  .. tu as raison -  
 
mais donc pas mieux  ?

Reply

Marsh Posté le 16-01-2006 à 14:48:59    

pas mieux??? quoi? Je ne comprend pas la question :)


---------------
MZP est de retour
Reply

Marsh Posté le 16-01-2006 à 14:57:28    

excuse .. je veux dire on peut donc pas faire un truc plus optimal que  
 
   1.
      SELECT DISTINCT *
   2.
      FROM manif LEFT JOIN villes ON villes.nom_ville=manifestation.manifestation_ville
   3.
      WHERE (manifestation_date_debut >='2006/01/16' OR manifestation_date_fin >='2006/01/16')
   4.
      AND villes.ref_pays='3'

Reply

Marsh Posté le 16-01-2006 à 14:59:49    

remplace le * par les champs que tu vas utiliser.  
jointure sur numerique plutot que texte et index.
index sur les dates.  
 
Mais les index feront dejà bcp. Ensuite, y'a moyen d'orienter l'optimiseur en jouant avec les conditions.


---------------
MZP est de retour
Reply

Marsh Posté le 16-01-2006 à 14:59:49   

Reply

Marsh Posté le 16-01-2006 à 15:05:00    

merci

Reply

Marsh Posté le 16-01-2006 à 15:05:30    

au plaisir.


---------------
MZP est de retour
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed