Question sur une requete MySQL

  • Auteur de la discussion Auteur de la discussion sim100
  • Date de début Date de début
WRInaute passionné
Bonjour,
Ma question est toute bête, est ce qu'une requête du style

Code:
$query="SELECT magasins.magasin, magasins.categorie, magasins.adresse, magasins.tel, magasins.commentaire, soldes.date_debut, soldes.date_fin, magasins.compteur, magasins.website, magasins.ville, magasins.cp, count(magasins.magasin) 

FROM villes, magasins, soldes 

WHERE soldes.magasin_id=magasins.compteur AND magasins.ville=villes.ville AND LEFT(villes.cp, 2) = LEFT(magasins.cp, 2) AND villes.dep=\"$ville[5]\" AND (TO_DAYS(soldes.date_fin) - TO_DAYS(NOW()) >= 0) 

GROUP BY magasins.magasin 

ORDER BY soldes.date_debut ASC";

peut être trop lourde, est ce qu'elle est mal faites?
En fait elle marche, mais je soupçonne qu'elle fasse planter ma base régulièrement...
Alors je sais bien que vous ne savez pas les tables qu'il y a derrière etc...
Mais peut être avez vous une idée, pour les pro, si au moins elle est mal construite.

J'insiste sur le count(magasins.magasin) et le GROUP BY, et un appel à 3 tables...

Merci pour vos avis
 
WRInaute accro
Ben:
- vu que tu as déjà un lien entre magasins et villes via la condition "magasins.ville=villes.ville", la condition "LEFT(villes.cp, 2) = LEFT(magasins.cp, 2)" est-elle vraiment nécessaire?
- quelles sont les tailles respectives des 3 tables?
- quels index as-tu mis sur tes tables?

De loin, je dirais qu'il te faut au moins des index sur:
- le champ dep de villes
- le champ ville de magasins
- le champ magasin_id de soldes

Alternativement (ça dépend de la taille respective de tes tables et du bout par lequel le serveur exécute la requête):
- remplacer la condition "TO_DAYS(soldes.date_fin) - TO_DAYS(NOW()) >= 0" par "soldes.date_fin > now()"
- mettre un index sur soldes.date_fin
- un index sur magasins.compteur
- un index sur villes.ville

Avec ça, ça devrait pouvoir aller assez vite.

Mysql peut être configuré pour logguer les requêtes qui prennent "trop" de temps (slow queries), pense à activer ça si ce n'est déjà fait, et à regarder ce qu'il dit... Tu peux aussi utiliser explain sur ta requête pour voir comment il l'exécute.

Jacques.
 
WRInaute passionné
Merci pour ces détails.

Alors j'ai déja arrangé l'affaire pour retirer effectivement l'accès à 1 champs.

Donc seulement 2 champs seront consultés.

Une question supplémentaire:
Est-il possible d'avoir plusieurs index par table ?
Je pense que oui, mais quelles sont les conséquenses? sinon ne serait-il pas plus simple de mettre des index sur tous les champs ?

Merci pour ces dernières détails
 
WRInaute accro
Oui, tu peux mettre des index sur plusieurs champs. L'inconvénient c'est à chaque modification (insert/update/delete), il faut mettre à jour chacun des index, donc si tu as beaucoup d'accès en écriture ça consomme plus en I/O disque, et évidemment ça prend plus de place sur disque. Et lors des requêtes, ça peut faire plus de boulot pour le serveur de trouver les bons index à utiliser s'il a plus de choix disponibles. Donc il vaut mieux ne mettre que les index qui sont réellement utiles.

Jacques.
 
WRInaute passionné
Comme ca mettre à jour les index.

En fait pour l'instant sur chaque table j'ai un index sur le champs "compteur" qui est un champs auto-increment
 
WRInaute accro
C'est le serveur mysql qui les met à jour pour toi, rien de manuel, mais ça veut dire que ça fait plus de boulot pour lui, ça consomme plus d'accès disque, plus de place sur le disque, plus de CPU, etc. Bref, ça "charge" ta machine pour rien si les index en question ne sont jamais utilisés.

Jacques.
 
WRInaute passionné
OK merci beaucoup pour toutes tes réponses claires et précises :)

Je pense être paré pour la suite.

Merci encore
 
Discussions similaires
Haut