Page 1 sur 1

Requête SQL trop lourde ?

Posté : 13 mai 2008, 09:57
par Thegritch
hello,

Je suis en train de réaliser un moteur de recherche pour un site web.
Ce dernier se base sur MYSQL et est composé de plusieurs tables :

=> Articles
=> Dossiers
=> Actualités
=> Évènements

Create_table classique :

Code : Tout sélectionner

CREATE TABLE `sj_article` ( `id_sj_article` int(5) NOT NULL auto_increment, `titre_chap_sj_article` varchar(80) NOT NULL, `desc_chap_sj_article` varchar(180) NOT NULL, `lien_sj_article` varchar(50) NOT NULL, `url_chap_sj_article` varchar(100) NOT NULL, `corps_sj_article` mediumtext NOT NULL, `date_creation_sj_article` datetime NOT NULL, `date_publication_sj_article` datetime NOT NULL, `date_modification_sj_article` datetime NOT NULL, `FK_id_sj_utilisateur` int(3) NOT NULL, `FK_id_sj_article_etat` int(2) NOT NULL, `FK_id_sj_ss_categorie` int(2) NOT NULL, PRIMARY KEY (`id_sj_article`), FULLTEXT KEY `titre_chap_sj_article` (`titre_chap_sj_article`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
J'utilise le LIKE comme mot clef.
Quand je place des "AND" entre mes thèmes (articles, etc.) le résultat est très rapide...
Mais quand je place des "OR" là le résultat prend bien plus de temps, ce que je peux comprendre, mais y'a t'il moyen d'améliorer les requêtes ?

Sachant que la recherche fulltext ne ma plait guère car il faut que la personne fasse une recherche basée sur plusieurs mots-clefs

Avec le AND

Code : Tout sélectionner

SELECT modge.* , cat.lib_sj_categorie , cat.id_sj_categorie , sscat.lib_sj_ss_categorie , modu.lib_sj_modules_theme , sscat.id_sj_ss_categorie FROM sj_modules_generique modge , sj_categorie cat , sj_ss_categorie sscat , sj_modules_theme modu , sj_modules_ss_theme ssmodu WHERE modge.etat_sj_modules_generique = 'OK' AND ( modge.keyword_sj_modules_generique LIKE '%pénurie%' OR modge.titre_01_sj_modules_generique LIKE '%pénurie%' OR modge.titre_02_sj_modules_generique LIKE '%pénurie%' OR modge.titre_03_sj_modules_generique LIKE '%pénurie%' OR modge.titre_04_sj_modules_generique LIKE '%pénurie%' OR modge.titre_05_sj_modules_generique LIKE '%pénurie%' OR modge.ss_titre_01_sj_modules_generique LIKE '%pénurie%' OR modge.ss_titre_02_sj_modules_generique LIKE '%pénurie%' OR modge.ss_titre_03_sj_modules_generique LIKE '%pénurie%' OR modge.ss_titre_04_sj_modules_generique LIKE '%pénurie%' OR modge.ss_titre_05_sj_modules_generique LIKE '%pénurie%' OR modge.texte_01_sj_modules_generique LIKE '%pénurie%' OR modge.texte_02_sj_modules_generique LIKE '%pénurie%' OR modge.texte_03_sj_modules_generique LIKE '%pénurie%' OR modge.texte_04_sj_modules_generique LIKE '%pénurie%' OR modge.texte_05_sj_modules_generique LIKE '%pénurie%' OR modge.explication_01_sj_modules_generique LIKE '%pénurie%' OR modge.explication_02_sj_modules_generique LIKE '%pénurie%' OR modge.explication_03_sj_modules_generique LIKE '%pénurie%' OR modge.explication_04_sj_modules_generique LIKE '%pénurie%' OR modge.explication_05_sj_modules_generique LIKE '%pénurie%' OR modge.form_adresse_sj_modules_generique LIKE '%pénurie%' OR modge.form_ville_sj_modules_generique LIKE '%pénurie%' ) AND ( modge.keyword_sj_modules_generique LIKE '%japon%' OR modge.titre_01_sj_modules_generique LIKE '%japon%' OR modge.titre_02_sj_modules_generique LIKE '%japon%' OR modge.titre_03_sj_modules_generique LIKE '%japon%' OR modge.titre_04_sj_modules_generique LIKE '%japon%' OR modge.titre_05_sj_modules_generique LIKE '%japon%' OR modge.ss_titre_01_sj_modules_generique LIKE '%japon%' OR modge.ss_titre_02_sj_modules_generique LIKE '%japon%' OR modge.ss_titre_03_sj_modules_generique LIKE '%japon%' OR modge.ss_titre_04_sj_modules_generique LIKE '%japon%' OR modge.ss_titre_05_sj_modules_generique LIKE '%japon%' OR modge.texte_01_sj_modules_generique LIKE '%japon%' OR modge.texte_02_sj_modules_generique LIKE '%japon%' OR modge.texte_03_sj_modules_generique LIKE '%japon%' OR modge.texte_04_sj_modules_generique LIKE '%japon%' OR modge.texte_05_sj_modules_generique LIKE '%japon%' OR modge.explication_01_sj_modules_generique LIKE '%japon%' OR modge.explication_02_sj_modules_generique LIKE '%japon%' OR modge.explication_03_sj_modules_generique LIKE '%japon%' OR modge.explication_04_sj_modules_generique LIKE '%japon%' OR modge.explication_05_sj_modules_generique LIKE '%japon%' OR modge.form_adresse_sj_modules_generique LIKE '%japon%' OR modge.form_ville_sj_modules_generique LIKE '%japon%' ) AND modge.fk_id_sj_ss_categorie = sscat.id_sj_ss_categorie AND sscat.FK_id_sj_categorie = cat.id_sj_categorie AND modge.FK_id_sj_modules_ss_theme = ssmodu.id_sj_modules_ss_theme AND ssmodu.FK_id_sj_modules_theme = modu.id_sj_modules_theme ORDER BY modge.date_publication_sj_modules_generique DESC
Avec le OR

Code : Tout sélectionner

SELECT modge.* , cat.lib_sj_categorie , cat.id_sj_categorie , sscat.lib_sj_ss_categorie , modu.lib_sj_modules_theme , sscat.id_sj_ss_categorie FROM sj_modules_generique modge , sj_categorie cat , sj_ss_categorie sscat , sj_modules_theme modu , sj_modules_ss_theme ssmodu WHERE modge.etat_sj_modules_generique = 'OK' AND ( modge.keyword_sj_modules_generique LIKE '%pénurie%' OR modge.titre_01_sj_modules_generique LIKE '%pénurie%' OR modge.titre_02_sj_modules_generique LIKE '%pénurie%' OR modge.titre_03_sj_modules_generique LIKE '%pénurie%' OR modge.titre_04_sj_modules_generique LIKE '%pénurie%' OR modge.titre_05_sj_modules_generique LIKE '%pénurie%' OR modge.ss_titre_01_sj_modules_generique LIKE '%pénurie%' OR modge.ss_titre_02_sj_modules_generique LIKE '%pénurie%' OR modge.ss_titre_03_sj_modules_generique LIKE '%pénurie%' OR modge.ss_titre_04_sj_modules_generique LIKE '%pénurie%' OR modge.ss_titre_05_sj_modules_generique LIKE '%pénurie%' OR modge.texte_01_sj_modules_generique LIKE '%pénurie%' OR modge.texte_02_sj_modules_generique LIKE '%pénurie%' OR modge.texte_03_sj_modules_generique LIKE '%pénurie%' OR modge.texte_04_sj_modules_generique LIKE '%pénurie%' OR modge.texte_05_sj_modules_generique LIKE '%pénurie%' OR modge.explication_01_sj_modules_generique LIKE '%pénurie%' OR modge.explication_02_sj_modules_generique LIKE '%pénurie%' OR modge.explication_03_sj_modules_generique LIKE '%pénurie%' OR modge.explication_04_sj_modules_generique LIKE '%pénurie%' OR modge.explication_05_sj_modules_generique LIKE '%pénurie%' OR modge.form_adresse_sj_modules_generique LIKE '%pénurie%' OR modge.form_ville_sj_modules_generique LIKE '%pénurie%' ) AND ( modge.keyword_sj_modules_generique LIKE '%japon%' OR modge.titre_01_sj_modules_generique LIKE '%japon%' OR modge.titre_02_sj_modules_generique LIKE '%japon%' OR modge.titre_03_sj_modules_generique LIKE '%japon%' OR modge.titre_04_sj_modules_generique LIKE '%japon%' OR modge.titre_05_sj_modules_generique LIKE '%japon%' OR modge.ss_titre_01_sj_modules_generique LIKE '%japon%' OR modge.ss_titre_02_sj_modules_generique LIKE '%japon%' OR modge.ss_titre_03_sj_modules_generique LIKE '%japon%' OR modge.ss_titre_04_sj_modules_generique LIKE '%japon%' OR modge.ss_titre_05_sj_modules_generique LIKE '%japon%' OR modge.texte_01_sj_modules_generique LIKE '%japon%' OR modge.texte_02_sj_modules_generique LIKE '%japon%' OR modge.texte_03_sj_modules_generique LIKE '%japon%' OR modge.texte_04_sj_modules_generique LIKE '%japon%' OR modge.texte_05_sj_modules_generique LIKE '%japon%' OR modge.explication_01_sj_modules_generique LIKE '%japon%' OR modge.explication_02_sj_modules_generique LIKE '%japon%' OR modge.explication_03_sj_modules_generique LIKE '%japon%' OR modge.explication_04_sj_modules_generique LIKE '%japon%' OR modge.explication_05_sj_modules_generique LIKE '%japon%' OR modge.form_adresse_sj_modules_generique LIKE '%japon%' OR modge.form_ville_sj_modules_generique LIKE '%japon%' ) AND modge.fk_id_sj_ss_categorie = sscat.id_sj_ss_categorie AND sscat.FK_id_sj_categorie = cat.id_sj_categorie AND modge.FK_id_sj_modules_ss_theme = ssmodu.id_sj_modules_ss_theme AND ssmodu.FK_id_sj_modules_theme = modu.id_sj_modules_theme ORDER BY modge.date_publication_sj_modules_generique DESC

Bref requête assez lourde.

Si vous avez des idées ou des pistes n'hésitait pas !!

Cordialement

Posté : 13 mai 2008, 10:02
par Berzemus
Salut,
Sachant que la recherche fulltext ne ma plait guère car il faut que la personne fasse une
recherche basée sur plusieurs mots-clefs
Tu pourrais être plus explicite la dessus ?

Like, c'est pratique parfois, mais pour chercher dans un champ mediumtext, c'est un peu de la folie. (c'est outrageusement lent)

Personnellement, j'utiliserais une autre table, ou toutes les valeurs sont concaténées, et dans laquelle tu fais une recherche full-text..

Posté : 13 mai 2008, 15:53
par caroube
La fonction fulltext, c'est quand même ce que MySQL a inventé de mieux pour faire de la recherche de plusieurs mots parmi plusieurs champs (l'index fulltext peut couvrir plusieurs colonnes de ta table)

Les LIKE '%texte%' sont à proscrire à cause de leur lenteur. Alors quand tu en as plusieurs, c'est l'horreur.
Quand tu cherches 'Dup%' dans un annuaire, tu vas assez vite à la page des D en ouvrant l'annuaire vers son début, puis en feuilletant les pages, tu arrives très vite à la page DU, puis à la colonne où se trouvent les Dupont et Dupond. Quand tu cherches '%ont', dans un annuaire, tu n'as pas d'autre solution que de parcourir l'annuaire page par page, nom par nom pour savoir s'il se termine par 'ont' ou pas. C'est exactement la même chose pour le SGBD avec quasiment le même rapport de temps entre rechercher 'Dup%' et rechercher '%ont'.