Page 1 sur 2
Nombre de requete sql maximum dans un script
Posté : 25 mai 2007, 16:18
par AS72
Bonjour,
Voilà, je developpe un site e-commerce. Sur la page résultat de recherche, j'ai un certain nombre de requete qui s'affiche. Pour chaque produit, je dois faire 1 requete qui va me récupérer son prix, puis me récupérer un certain nombre de services. Pour chaque services, je doit récupéré sa disponibilité, son prix.
Sur une page présentant environ 15 produits j'en suis actuellement à près de 800 requète sql. Dans les 800, je doit en avoir 780 qui sont des requètes extrenement simple et rapide. J'ai optimisé un maximum en utilisant des jointures mais il arrive un moment où je n'ai pas le choix.
A votre avis, est-ce lourd de réaliser 800 requètes? La page se charge quasi instantanément, je ne perçoi strictement aucun ralentissement.
Merci.
Posté : 25 mai 2007, 16:21
par Cyrano
800 requête pour une seule page ????? ça fait à mon sens environ 790 de trop. Tu dis avoir utilisé les jointures, mais probablement pas suffisamment. Si en plus c'est pour un site de e-commerce, imagine un peu que le trafic augmente et que tu aies 200 internautes simultanément : tu vas faire exploser ton serveur de base de données et le DBA va t'envoyer les félicitations du jury avec mention

Posté : 25 mai 2007, 16:27
par AS72
Le problème c'est que j'ai une class qui va me récupérer un tarif (avec les reductions, type de majoration, ...) pour un produit ou un service.
Alors quand j'ai 15 produits qui s'affichent et qu'ils possèdent chacun une vingtaine de services, ça me fait un sacré nombre de requête juste pour les tarifs. Je ne parle pas des disponibilités....
Posté : 25 mai 2007, 16:45
par mere-teresa
En fait, comment peux-tu récupérer des informations sur plusieurs produits à la fois en SQL ?
Posté : 25 mai 2007, 17:01
par AS72
En fait je travail sur un gros site d'agence de voyage. Notre base de donnée est alimentée par environ 600 annonceurs (agence de voyage...) et diffusée sur plus de 300 autres sites internet (commercialisateurs).
Lorsque que j'affiche mes 15 séjours dans ma page de recherche, j'ai du préalablement calculée la disponibilité de celui-ci en fonction de plusieurs critères définis par l'annonceur et le commercialisateur, en fonction des dates (courts séjourt, semaine, multi-semaine, semaine chevauchante). Je doit également récupéré les tarifs qui prend en compte près de 5 majorations. Il m'est absolument impossible récupéré les infos d'hebergement accompagnée de la disponibilité et des tarifs en 1 requete il m'en faut 3.
Après pour chaque hébergement, je récupère la liste des service associé et standard liés soit à un annonceur, soit à une station, soit à l'hebergement à celui-ci (ex: assurance, remontées mécanique, ...). Je peut en récupéré jusqu'à une vingtaine voir beaocoup plus. Pour chaque service, je dois calculer dispo et prix, ce sont exactement les même requetes que pour l'hébergement.
Je récupère également pour chaque hébergement, 3 autres capacités de couchage disponibles dans le même domaine, ou dans la même station ou dans la même residence se rapprochant le plus de l'hébergement issu de la recherche. Pour chaqun des 3, il me faut également un calcul de dispo et de tarifs.
Et encore, je ne rentre pas du tout dans les détails, je travail sur un système qui existe depuis plus de 6 ans, faut voir le nombre de tables et d'élements qui composent la base de donnée.
Voilà, j'ai optimiser au maximum mon script, l'ancienne version du site nous généré quand même près de 3000 requètes et été vraiment long à afficher.
Re: Nombre de requete sql maximum dans un script
Posté : 25 mai 2007, 21:19
par Hubert Roksor
A votre avis, est-ce lourd de réaliser 800 requètes?
Sur une page de maintenance que tu lances toutes les semaines à 4h du matin, non, tu peux en exécuter 2000 si tu veux, c'est pas un problème. Maintenant, sur une page publiquement accessible dont tu ne peux pas contrôler la charge alors oui, tu risques de voir ton site faire une crise cardiaque, littéralement.
La page se charge quasi instantanément, je ne perçoi strictement aucun ralentissement.
Malheureusement c'est une illusion très courante (c'est arrivé à peu près à tous les sites du monde). Quand on teste, à vue de nez ça a l'air rapide, quand on fait des microbenchmarks tout est super optimisé et le jour où l'adresse attérit sur Digg/Yahoo ou la dernière page d'Entrevue le serveur s'effondre. En conditions réelles, les requêtes sont généralement plus diverses, portent sur toutes les données de ta base, les caches d'index expirent, le cache de requête de MySQL aussi, etc...
Ce que je te recommande c'est de poster les requêtes représentatives des 800 requêtes dont tu parlais plus haut (en gros poste l'exemple d'une vraie requête pour chaque type de requêtes différent) avec une estimation du nombre de fois que ce type de requête est exécuté page page, ainsi que le schema des tables qui y sont liées. De cette façon quelqu'un aura certainement une idée pour récupérer tes données de façon plus efficace.
Posté : 28 mai 2007, 10:12
par mere-teresa
Il existe des outils de tests de charge, comme PHPMeter qui simule la connexion de N utilisateurs à ton site.
Pour les requêtes, est-il possible de faire ces requêtes la nuit, et de stocker leur résultat sous forme de table temporaire (soit des vues si ton SGBD te le permet, soit des tables que tu recrées chaque nuit que tu mets à jour) ?
Posté : 29 mai 2007, 10:25
par AS72
J'ai reussi à optimiser un peu le tout en modifiant mon algo, je me retrouve désormais avec environ 100 requetes.
Je ne peux malheureusement pas poster mes requetes. Elles sont vraiment énormes et sont générées via un algo. Leurs formes peuvent carrément changer suivant les criteres de recherche indiqués.
En gros pour l'instant j'ai une requete générale de recherche qui va me retourner une liste de 15 id hebergement triée selon les critères. Cette requete est assez grosse mais parait extrenement rapide, il doit y avoir environ 10 tables de jointes (je ne sais pas si c'est l'idéal, mais fragementer la requete revient à faire une usine à gaz (existant)) et je ne peux me passer d'une de ces tables.
Cette requête est réalisée une seule fois.
Puis j'en ai une deuxième assez grosse également (6 tables et 3 UNIONS) qui va me récupérer la liste des services associé à chaque hébergement, station et résidence (d'où les 3 UNIONS). Elles exécutés autant de fois qu'il y a d'hébergement (ici 15 fois).
Après j'ai mes requêtes de dispo, tarifs qui vont s'appliquer pour chaque hebergement et services. Ce sont des requetes toutes simples qui ne font appel qu'à 2 voir 3 tables. Ce sont elles qui représentent la plus grosse partie.
Et enfin pour chaque hébergement, je dois récupéré une liste d'autre hébergement étant dans la même résidence mais d'une capacité différente (c'est pour un encart "autres capacité disponibles"). Donc là, 1 requète pour chaque hébergement + requete dispo et prix pour chaque resultats.
Il m'est impossible de générer le résultats la nuit, il existe beaucoup trop de cas possible, le moteur de recherche possédant énormement d'options. De plus une multitudes de passerelles tournent la journée et alimentent la table.
Posté : 29 mai 2007, 10:48
par Hubert Roksor
J'ai reussi à optimiser un peu le tout en modifiant mon algo, je me retrouve désormais avec environ 100 requetes.
Je ne peux malheureusement pas poster mes requetes.
800, 100, ce sont des chiffres. Ils n'ont aucune signification si on ne sait pas ce que sont ces requêtes.
Elles sont vraiment énormes
Ça c'est pas super bon signe...
et sont générées via un algo.
...et ça c'est carrément bizarre. À moins que tu ne fasses références à l'ajout de certains critères selon la recherche ?
En gros pour l'instant j'ai [...]
Sans plus d'information sur tes tables ou tes requêtes personne ne pourra t'apporter d'aide pertinente. On pourrait balancer des trucs bateau, mais honnêtement ça ne servirait à personne.
Si tes requêtes sont "grosses" à cause d'un IN() à rallonge alors tu cours le risque de planter à partir d'une certaine taille, sans parler des performances qui sont généralement très sous-optimales. Malgré tout, tu pourrais poster ladite requête en ellipsant le contenu du IN.
Elles exécutés autant de fois qu'il y a d'hébergement (ici 15 fois).
1 requète pour chaque hébergement
Là encore, exécuter la même requête avec un paramètre qui change est mauvais signe. Tu devrais chercher à remplacer cette boucle par une jointure.
Comme je le disais plus haut, poste le schéma des tables pertinentes (les tables centrales, tu peux oublier celles qui ne contiennent que des critères de recherches), classe tes requêtes par catégorie et montre-nous les requêtes en question, ce sera beaucoup plus efficace.

Posté : 29 mai 2007, 11:06
par AS72
Je ne pense pas que celà soit forcement bizzare de générer une requete de recherche via un algo, la requete change de forme en fonction de la date et de la durée (recherche en court séjour, semaine, multi semaine, départ en mileu de semaine, ...), en fonction des critères géographiques (juste le pays de précisé, ou pays + region, +departement, +station) et sans compter les nombreuses options (tarifs, capacité, type d'hébergement (hotel, location, ...))
Maintenant, poster des requetes ou une partie de la base, je ne pense pas que ce soit vraiment possible, je vais mettre la journée

, les tables sont tellement grosse, il y en a tellement et tout est important.
Nous pensons aujourd'hui que le problème est la conception de cette base. Malheureusement il est impossible pour nous de la refondre ou ne serait-ce que la modifier légèrement. Celà reviendrai à refaire tout le back office et modifier près de 300 passerelles du côté fournisseurs.
Concernant de ces requetes qui sont générées 1 seules fois par hébergement. Oui elles sont petites, oui elles pourraient s'intégrer dans la grosse requete de recherche. Mais celà alourdirait cette dernière. De plus ma requète tarifs est dans une classe tarifs dont j'ai besoin d'accéder depuis n'importe où sur le site.
Pourquoi récupérer les tarifs dans ma requete de recherche si une classe est là pour le faire ? Car il y a une gros traitement de majorations réalisée dans cette classe, je ne vais quand même pas dupliquer toute une partie de mon algo (requete tarifs + calcul majoration)?
Posté : 29 mai 2007, 11:11
par Hubert Roksor
Si tu ne peux décrire ni ton schéma ni tes requêtes et que tu ne comptes pas modifier ni ton schéma ni tes requêtes voici mon avis : mets plus de RAM, il n'y a rien que l'on puisse faire pour toi.
Posté : 29 mai 2007, 11:26
par AS72
Oui c'est ce qu'on a du faire pour la saison dernière, le serveur claquait tous les soirs, hop, petite barette et tout est rentré dans l'ordre malgrés de fort ralentissement à certaines heures.
Faut dire que le site été une usine à gaz, faire une requete qui te rapatrie 1500 id_hebergement puis tu boucle dessus et tu fait 3/4 requetes pour trier les résultat et au final n'afficher que les 15 premiers.
Surtout que les requetes étaient toutes du type "SELECT a.*, b.*, c.*, d.*, e.* FROM ..." (il y a même une requete qui monte jusque la lettre j comme çà et faut voir la taille des tables, 50 champs pour 2/3 d'entre elles).
Je vous remercie tous de m'avoir bien éclairer tout de même mais ce n'est pas un problème qui se resolvera en 10 minutes je pense surtout si je poste les requetes et le schema des tables.
C'est le problème quand les choses sont mal conçues dès le départ et qu'il arrive un moment où ça ne tient plus mais qu'il est impossible modifier quoique ce soit en profondeur sous peine de se retaper 6 années de travail.
Donc seule une refonte du site en améliorant considérablement l'algo et en partie les requêtes et l'ajout de ram permettera de passer la saison prochaine mais je ne sais pas combien d'année ça tiendra comme ça.

Posté : 29 mai 2007, 14:56
par Sékiltoyai
C'est le problème quand les choses sont mal conçues dès le départ et qu'il arrive un moment où ça ne tient plus mais qu'il est impossible modifier quoique ce soit en profondeur sous peine de se retaper 6 années de travail.
Changer l'architecture d'une base ne prend pas 6 années de travail, mais une bonne conception, une coupure temporaire de la production (ca se fait donc pendant l'automne dans ce cas précis, ou à la rigueur l'hiver), des grosses requètes, procédures, et scripts de transformation, et puis des serveurs de calcul derrière pour faire le boulot. Et selon la puissance fournie, en quelques jours, heures ou minutes, tu as une nouvelle architecture prête à supporter des charges plus lourdes...
Posté : 29 mai 2007, 15:27
par AS72
Hum quand tu as 300 passerelles différentes qui tournent pour alimenter notre base et 600 commercialisateurs qui viennent piochez nos offres tous les jours dans celle-ci, peut te garantir que modifier la base serait une pure folie.
Tu ne peux pas imaginer la galère que c'est lorsqu'on doit modifier 1 passerelle juste pour 1 donnée quand tu as des gens qui ne comprennent rien en face de toi. Et juste pour rappel, toutes les passerelles sont différents (et celà a bien mis 6 ans a tout concevoir, la modification ne prendra pas 2 jours).
C'est déjà énorme d'avoir pu convaincre mes patrons de faire la refonte du site, je ne tenterais jamais la refonte de la base et tout ce que celà impliquerez notament la modification en profondeur du backoffice qui est relativement conséquent.
Nous sommes une plateforme d'agence de voyage alimentée par 300 annonceurs et commercialisant nos offres sur les plus gros sites de voyage en France, on ne change pas toute la base et on va pas faire chier tout nos partenaires sous pretexte qu'elle est légèrement mal concue et qu'elle va ralentir en partie notre site à cause de ces requetes.
Donc voilà, je ne peux rien faire de ce côté là
Sinon j'avais soulevé un problème plus haut
Concernant de ces requetes qui sont générées 1 seules fois par hébergement. Oui elles sont petites, oui elles pourraient s'intégrer dans la grosse requete de recherche. Mais celà alourdirait cette dernière. De plus ma requète tarifs est dans une classe tarifs dont j'ai besoin d'accéder depuis n'importe où sur le site.
Pourquoi récupérer les tarifs dans ma requete de recherche si une classe est là pour le faire ? Car il y a une gros traitement de majorations réalisée dans cette classe, je ne vais quand même pas dupliquer toute une partie de mon algo (requete tarifs + calcul majoration)?
Quelqu'un aurait une idée? Laisser mon appel de ma classe contenant une petite requete pour chaque résultat ou dupliquer tout le contenu de cette classe dans celle de recherche et intégrer la ptite requete dans la grosse de recherche? Merci.
Posté : 29 mai 2007, 16:12
par Sékiltoyai
C'est déjà énorme d'avoir pu convaincre mes patrons de faire la refonte du site, je ne tenterais jamais la refonte de la base et tout ce que celà impliquerez notament la modification en profondeur du backoffice qui est relativement conséquent.
Ce genre de choses là, ce sont des questions managériales plus que technique. Je n'ai jamais dit que c'était une mesure que le développeur prend indépendamment, au contraire, c'est toute la politique d'une entreprise qui entre en compte pour des modifications de cette sorte.