Aller au contenu

optimisation des requetes sql


davidc1

Sujets conseillés

Bonjour,

J'ai réalisé un comparateur de prix, la base de donnée est mysql. J'utilise un index fulltext pour y rechercher les articles par mots clés, un exemple de requête qui va chercher le mot "essai" dans le titre est :

SELECT * FROM osc WHERE MATCH (BHTTL) AGAINST ('+essai*' IN BOOLEAN MODE)

En ajoutant la possibilité de restreindre à une seule boutique (id=237) ça donne :

SELECT * FROM osc WHERE MATCH (BHTTL) AGAINST ('+essai)*' IN BOOLEAN MODE) AND BHSELLER = '237'

Ces deux requêtes fonctionnent bien (il n'y a que BHTTL qui existe comme indexs fulltext) et renvoient des résultats rapidement.

Mon problème est quand je cherche tous les articles d'une boutique uniquement, la requête est :

SELECT * FROM osc WHERE BHSELLER=237

Cette fois ça met beaucoup plus de temps... c'est catastrophique. Quelle optimisation (base, requête...) pourrais-je faire pour que ça fonctionne correctement :?:

Si vous avez besoin de plus de renseignements n'hésitez pas.

Merci par avance,

david.

**EDIT** Modérateur (TheRec): Merci d'utiliser les BBCodes pour présenter du code, en l'occurrence la balise SQL ou CODE :)

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

Et si tu n'as pas défini d'INDEX (simple... pas FULLTEXT) sur le champ BHSELLER, il faut le faire.

Je ne peux pas garantir un impact sur le performance, mais il faut également éviter (par pure logique de typage) de donner une valeur sous forme de chaîne de caractère (p.e. BHSELLER = '237') alors que le champ est un entier (enfin selon toute logique... si c'est un id ;))... MySQL fait le transtypage sans problème mais je suppose que cela consomme tout de même plus de ressource (enfin pas énormément non plus)

Si tu peux nous présenter la structure de ta table (que tu obtiens en exportant ta table avec un outil comme PHPMyAdmin ou même mysql_dump), cela nous aidera dans la résolution de ton problème.

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

En partie d'accord avec tous le monde, l'index est important pour un accès rapide aux données; quand à select champ1,champ2 au lieu de select * ça reste pour moi à vérifier, je n'en suis pas sur...car evidement ça dépend de la base de donnees : tables et jointures qui sont effectuées dans la clause select ...

A ce titre, pourrais tu indiquer :

1 - La table osc (celle sur laquelle tu fais tes requêtes) combien de champs elle comporte, mais aussi combien d'enregistements ?

Cette fois ça met beaucoup plus de temps... c'est catastrophique
2 - Ca veut dire quoi catastrophique ? 5 secondes 10, 25 ?

3 - Ton serveur mysql il en en local genre easyphp ? sur une machine distante dediée, fédérée ?

Merci

En espérant pouvoir amener une réponse...

Lien vers le commentaire
Partager sur d’autres sites

J'avais essayé de créer l'index sur bhseller auparavant mais ça n'avait rien changé.

je viens de m'apercevoir que BHSELLER était en char, je l'utilisais pas comme id avant, j'ai fait la modif et l'ai mis en int.

j'ai créé l'index sur BHSELLER.

Et maintenant ça marche du tonerre !

Merci pour votre aide, deuxième fois que j'arrive avec des questions ici et que les problèmes sont résolus rapidement.

le moteur fonctionne super avec 700000 articles !

david.

Lien vers le commentaire
Partager sur d’autres sites

Trés bien..

j'ai indirectement la réponse à mes questions posées...et donc mes doutes sont levés : la clause select n'est pas en cause...

Merci pour ta réponse ...

Lien vers le commentaire
Partager sur d’autres sites

Ce n'est pas parce qu'on a réussi à l'améliorer avec un index sur un champ de type INT que le SELECT ne peut pas non plus être amélioré.

En effet, sur une table comportant beaucoup de champs, et sur un traitement ne nécéssitant pas l'ensemble des données, on surcharge le serveur pour rien.

Ensuite, effectivement, l'impact est moindre.

Lien vers le commentaire
Partager sur d’autres sites

baboon> C'est assez "facile" de tester ce que tu avances plus haut, en utilisant le benchmark fourni par MySQL :

BENCHMARK(nombre_de_fois,expression)

Dans notre cas il suffit de comparer les résultats de temps obtenus avec une fois :

SELECT BENCHMARK(10000000,'SELECT * FROM osc');

et

SELECT BENCHMARK(10000000,'SELECT le_champ_id FROM osc');

J'ai fait exprès d'exagérer le nombre d'exécution, le teste peut prendre plusieurs secondes mais c'est un bon moyen de voir une différence significative entre les deux solutions... et en définitive on s'aperçoit qu'effectivement les deux solutions obtiennent sensiblement les même résultats. La différence se verra à mon avis lors du traitement des données, moins de données a récupérer, moins de temps processeur et de mémoire à utiliser.

Lien vers le commentaire
Partager sur d’autres sites

TheRec>

Merci pour les requêtes de BENCHMARK ...mais j'en ai que faire....ce n'est pas moi qui à la base...ton post n'est pas plutôt pour davidc1 ?

Cela dis cela reste interressant dans le principe .... pour tester rapidement. De plus probablement plus fiable que le temps d'exécution affiché par phpmyadmin sur l'exécution d'une requête sur lequel on effectuerai un multiplication...

Mais aussi, moins fiable qu'un générateur de données qui permet de créer une base de données test avec un grand nombre d'enregistrement, et donc avec un comportement plus proche de la réalité : les temps d'éxécution sont alors mesurés et non calculés....et ils tiennent donc compte d'autres facteurs limitants ... comme le processeur, la memoire et les disques, les caches, ...etc...

Bon week end

Lien vers le commentaire
Partager sur d’autres sites

En partie d'accord avec tous le monde, l'index est important pour un accès rapide aux données; quand à select champ1,champ2 au lieu de select * ça reste pour moi à vérifier, je n'en suis pas sur...

Non c'est bien à toi que je m'adresse, bien que tu ne soit pas la personne ayant commencé ce sujet ;)

Je te réponds au sujet des performances du "SELECT *" car tu semblais te poser des questions... je t'expliquais comment prouver ce que tu avançais (sans vraiment être sûr de toi), mais j'ai utilisé les informations qu'avait donné davidc1 uniquement à titre d'exemple :)

Et effectivement cela permet d'effectuer des mesures sur des données... il faut le coupler à un générateur de données bien entendu.

Lien vers le commentaire
Partager sur d’autres sites

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...