|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Invité régulier
![]() Inscription : janvier 2010 Messages : 32 ![]() |
Bonjour,
je suis en train de créer un site multilingue et actuellement j'essaye d'améliorer les performances de mon application. J'ai une requête qui consomme bcp de ressources, les résultats inutiles peuvent monter jusqu’à 50% ! Passons aux choses sérieuses ^^ Voici le schéma des tables utiles : ![]() Voici la requête MYSQL utilisée pour récupéré les produits correspondant à une catégorie ainsi qu'à ses sous-catégories : Code :
Le problème avec cette requête (elle fonctionne mais trop gourmande), c'est la dernière ligne. En effet, je suis sensé récupérer les produits traduits dans la langues choisie par le visiteur. Sauf que si la traduction n'existe pas, il doit quand même récupéré le produit mais avec la langue par défaut (qui sera toujours présente). Donc avec cette requête, dès que je vais choisir une langue (qui n'est pas celle par défaut), j'aurai à chaque fois des doublons inutiles ( une fois dans la langue choisie si elle existe et une fois dans la langue par défaut). Et quand on commence à avoir bcp de produits, la mémoire allouée est insuffisante pour récupéré tous les résultats de la requête ( +/- 15 000 enregistrements avec un fetchAll()). Serait-il possible de modifier la requête pour éviter ses doublons et alléger mon fetchAll final ? Bonne journée |
||
|
|
00
|
|
|
#2 |
|
Membre émérite
![]() Inscription : mai 2004 Messages : 739 ![]() |
Tu peux filtrer ta table product_lang.
Par exemple (c'est la première idée qui me vient, il y a certainement mieux), tu sélectionnes tous les product_id, language_id avec language_id = 'en' ou 'fr' et tu ajoutes un champ qui donne le nombre de lignes agrégées par product_id. Il te reste plus qu'à récupérer uniquement les lignes avec : nombre = 1 or (nombre = 2 and language_id = 'en').
__________________
Je ne réponds pas aux questions techniques par MP, le forum est là pour cela. La crypto c'est comme les flambys, une fois que tu as trouvé la languette tu as juste à tirer pour tout faire tomber. (\ _ /) (='.'=) Voici Lapinou. Aidez le à conquérir le monde (")-(") en le reproduisant |
|
|
00
|
|
|
#3 | ||
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
Bonjour,
Vous devriez commencer par remplacer le * par la liste exhaustives colonnes qui vous intéressent. C'est plus lisible, donc plus maintenable, et surtout cela demande moins de ressources, en évitant de "manipuler" des informations inutiles, voire d’éviter d'aller chercher dans la table si toutes les informations dont vous avez besoin existent dans un index (index couvrant) Ensuite, pour votre problème de langue par défaut, vous pouvez faire deux jointures externes, une pour la langue définie (tel que vous faites avec 'en' dans votre exemple) et une autre pour la langue par défaut Il ne vous restera plus qu'a prendre les colonnes de la deuxième jointure (langue par defaut) si celles de la langue 'en' sont NULL, pour cela, vous pouvez utiliser COALESCE qui renvoie la première valeur non NULL. Vous pouvez aussi remplacer votre sous requête par une jointure interne Enfin, vous pouvez remplacer vos LIKE par des = ça donnerait quelque chose comme : Code SQL :
|
||
|
|
10
|
|
|
#4 | |
|
Invité régulier
![]() Inscription : janvier 2010 Messages : 32 ![]() |
Bonjour,
merci à tous les deux pour vos réponses. @Drizzt [Drone38] : Pas bête, je vais tester. @aieeeuuuuu : Merci pour les différentes optimisations proposées, c'est toujours bon à savoir Je vais regarder de plus près, l'explication et l'exemple que tu proposes, surtout la fonction COALESCE que je ne connais pas. Concernant le *, c'est parce que dans ce cas-ci j'utilise toutes les colonnes récupérées (construction de mon objet php). Sinon, oui j'ai la possibilité de ne sélectionner que certaines colonnes ^^ Citation:
Merci pour vos conseils |
|
|
|
00
|
|
|
#5 | ||
|
Invité régulier
![]() Inscription : janvier 2010 Messages : 32 ![]() |
C'est de nouveau moi ^^
Je viens de tester ta solution, la requête fonctionne mais je n'obtient que les produits qui ont une traduction en Anglais. Ceux qui n'ont pas de traductions Anglaise mais dans la langue par défaut ne sont pas sélectionner. Une petite idée d’où pourrait venir l'erreur ? Voici la requête obtenue après les changements : Code :
|
||
|
|
00
|
|
|
#6 | ||
![]() ![]() ![]() Cédric DuprezInscription : avril 2002 Messages : 3 823 ![]() |
Oui, c'est parce qu'il faut mettre la condition sur la langue anglaise dans la jointure et non pas dans le WHERE :
Code :
__________________
Rédacteur / Modérateur SGBD Mes tutoriels et la FAQ MySQL ---------------------------------------------------- Pensez aux balises code et au tag Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
|
||
|
|
10
|
|
|
#7 |
|
Membre Expert
![]() Inscription : mars 2005 Messages : 1 565 ![]() |
Vous filtrez une colonne issue d'une table provenant d'une jointure externe.
|
|
|
00
|
|
|
#8 |
|
Invité régulier
![]() Inscription : janvier 2010 Messages : 32 ![]() |
En effet, je viens de comprendre le tout grâce à ca
Merci bcp, ca fonctionne ^^ Ma bd va pouvoir souffler |
|
|
00
|
|
|
#9 |
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
mea culpa, ça m'a échappé en modifiant la requête, mais effectivement, avec la condition sur la langue dans la clause WHERE, ça doit marcher beaucoup moins bien
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com