Serveur explosé à coups de lance requettes

Petit nouveau ! | 4 Messages

14 sept. 2006, 17:52

Bonjour, J'essai de faire un petit moteur de recherche
il y a dans la table les champs titre adresse description et je veux mettre en premier les sites qui ont le mot dans les 3 champs
en decond ceux qui ont le mot dans 2 champs
en dernier ceux qui ont le mot dans un champ
et je veux récupérer le nomnre derésultats

Je débute et je ne sais pas comment il est possible d'optimiser
avec 500 000 sites cela met 10s pour une recherche
j'imagine que quand il y aura 3 millions de sites j'aurai le temps d'aller faire un café :D (même si je n'en bois pas)

Si vous avez une idée

$sql_entete = "SELECT * FROM site WHERE 1=1 ";
$sql_entete_compteur = "SELECT * FROM site WHERE 1=1 ";
$sql = "";
// si requete la plus selective = vide alors faire la moins restrictive seulement
foreach($recherche as $val_recherche) { 
    $sql.=" and (adresse LIKE '%$val_recherche%'  AND titre LIKE '% $val_recherche %' AND  description LIKE '% $val_recherche %') "; 
    } 
$sql.=" LIMIT ".PAGE*$nbrpp.",".$nbrpp;	//nbpp nbr sites par page

$sql.="  UNION SELECT * FROM site WHERE 1=1 ";
foreach($recherche as $val_recherche) { 
    $sql.=" and ( adresse LIKE '% $val_recherche%' AND (titre LIKE '% $val_recherche %' OR description LIKE '% $val_recherche %')) "; 
    } 
$sql.=" LIMIT ".PAGE*$nbrpp.",".$nbrpp;	//nbpp nbr sites par page

$sql.="  UNION SELECT * FROM site WHERE 1=1 ";
foreach($recherche as $val_recherche) { 
    $sql.=" and ( description LIKE '% $val_recherche %' AND titre LIKE '%$val_recherche%') "; 
    } 
$sql.=" LIMIT ".PAGE*$nbrpp.",".$nbrpp;	//nbpp nbr sites par page

 
$sql.="  UNION SELECT * FROM site WHERE 1=1 ";
foreach($recherche as $val_recherche) { 
    $sql.=" and ( description LIKE '% $val_recherche %' OR titre LIKE '% $val_recherche %' OR adresse LIKE '%$val_recherche%' ) "; 
    } 
	
$sql_compteur= $sql;
$sql.=" LIMIT ".PAGE*$nbrpp.",".$nbrpp;	//nbpp nbr sites par page
/*
echo '</b><br><br>';
echo $sql;
echo '</b><br><br>';
*/


$resultat= mysql_query($sql_entete.$sql)or die ('ERREUR '.mysql_error());
$resultat_compteur= mysql_query($sql_entete_compteur.$sql_compteur)or die ('ERREUR '.mysql_error());
[/php]

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

16 sept. 2006, 18:28

moteur de recherche
"explosé" + "moteur de recherche" = Recherche en texte intégral (Full-text) dans MySQL

Pas la peine de chercher plus loin, on ne peut pas faire un moteur de recherche décent basé sur LIKE.

Eléphant du PHP | 332 Messages

17 sept. 2006, 09:19

Code : Tout sélectionner

titre LIKE '%$val_recherche%'
Il faut comprendre comment fonctionne le LIKE. On va faire une analogie avec la recherche d'un mot dans un dictionnaire (version papier).

- Soit tu connais les premières lettres (INFO par exemple) : en 3 ou 4 tournages de pages tu es à la lettre I, encore 2 ou 3 pages à tourner et tu es sur la page des INF et là tu trouves rapidement la définition du mot INFORMATIQUE. Tu viens de faire un LIKE 'INFO%' et ça a demandé quelques secondes.

- Soit tu ne connais pas les premières lettres et tu sais seulement que ton mot se termine par "TIQUE". Il n'y a pas d'autre solution que de parcourir le dictionnaire page par page, mot par mot jusqu'à ce que tu tombes sur le mot recherché "ZYGOMATIQUE". Ca t'aura demandé 5 heures et tu auras fait un LIKE '%TIQUE'.

- Soit tu connais quelques lettres du mot et tu vas donc faire un LIKE '%CAR%', ce qui nécessite le même parcours systématique de tout le dictionnaire et sensiblement le même temps de recherche.

C'est exactement le même fonctionnement avec le moteur de bases de données. Même si c'est syntaxiquement correct, un LIKE ne doit jamais commencer par un %. Tu peux faire des LIKE 'a%' tant que tu veux, mais jamais des LIKE '%a'.

Comme dit Hubert, il faut que tu te tournes vers le moteur Fulltext. D'autant plus qu'avec MySQL, tu peux indexer tes 3 champs simultanément.

Petit nouveau ! | 4 Messages

17 sept. 2006, 14:41

Merci pour l'url et pour les explications
du coup cela c'est transformé en
SELECT `adresse` , `titre` , `description` , MATCH (`adresse` , `description` , `titre` )AGAINST ('".$recherche."') AS score FROM sites WHERE MATCH (`adresse` , `description` , `titre` )AGAINST ('".$recherche."')
J'ai bien patogé pour créer les index fulltext surtout multi colones, mais c'est comme cela qu'on mémorise...

Il reste juste le COUNT (*) que je n'arrive pas à faire, mais je n'ai pas encore épuisé la doc indiquée

Merci bcp en tout cas cela à divisé par 20 le temps pour une recherche