IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

optimisation d'une requete


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 80
    Points : 53
    Points
    53
    Par défaut optimisation d'une requete
    Bonjour,

    Je viens vers vous car j'ai une requete que je dois optimiser mais je n'arrive pas a faire, la voici...
    Pour info, je suis sur mysql

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select distinct p.products_image, m.manufacturers_id, p.products_id, pd.products_name, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from products p 
    left join manufacturers m using(manufacturers_id) left join specials s on p.products_id = s.products_id, products_description pd, categories c, products_to_categories p2c 
    where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '4' and p.products_id = p2c.products_id and p2c.categories_id = c.categories_id and 
    ((pd.products_name like '%a%' or p.products_model like '%a%' or m.manufacturers_name like '%a%') ) 
    order by pd.products_name limit 0, 50
    D'avance merci

  2. #2
    Membre éprouvé Avatar de Mathusalem
    Profil pro
    IT moa
    Inscrit en
    Décembre 2003
    Messages
    1 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : IT moa

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 008
    Points : 1 067
    Points
    1 067
    Par défaut
    tu ne veux pas indenter un peu ton code ? là c'est vraiment pénible à déchiffrer

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 80
    Points : 53
    Points
    53
    Par défaut
    si pardon


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    SELECT DISTINCT p.products_image, m.manufacturers_id, p.products_id, pd.products_name, p.products_price, p.products_tax_class_id, IF( s.status, s.specials_new_products_price, NULL ) AS specials_new_products_price, IF( s.status, s.specials_new_products_price, p.products_price ) AS final_price
    FROM products p
    LEFT JOIN manufacturers m
    USING ( manufacturers_id ) 
    LEFT JOIN specials s ON p.products_id = s.products_id, products_description pd, categories c, products_to_categories p2c
    WHERE p.products_status = '1'
    AND p.products_id = pd.products_id
    AND pd.language_id = '4'
    AND p.products_id = p2c.products_id
    AND p2c.categories_id = c.categories_id
    AND (
    (
    pd.products_name LIKE '%a%'
    OR p.products_model LIKE '%a%'
    OR m.manufacturers_name LIKE '%a%'
    )
    )
    ORDER BY pd.products_name
    LIMIT 0 , 50

  4. #4
    Membre éprouvé Avatar de Mathusalem
    Profil pro
    IT moa
    Inscrit en
    Décembre 2003
    Messages
    1 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : IT moa

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 008
    Points : 1 067
    Points
    1 067
    Par défaut
    2 idées rapides :
    *tu mélanges des jointures correctes avec des jointures dans le where, essaye de tout faire avec des join (inner join).
    * le distinct est-il vraiment nécessaire ?

    sinon les like par 3 sont certainement consommateurs de temps.

  5. #5
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 115
    Points : 28 480
    Points
    28 480
    Par défaut
    Première opération : Rendre la requête plus lisible en utilisant des jointures normalisées.
    Deuxième opération : S'assurer que des index existent pour toutes les colonnes utilisées dans les jointures

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 920
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 920
    Points : 51 712
    Points
    51 712
    Billets dans le blog
    6
    Par défaut
    Beaucoup d'horreur dans votre requête :
    1) le mélange de jointure dans la clause WHERE et avec des joins. Ne faites que des JOINS
    2) des nombres ne se spécifient pas avec une chaine de caractères !
    Lorsque vous faites : MaColonne = '1' si macolonne est un nombre, vous obligez en faite le moteur à faire l'opération suivante :
    CAST(MaColonne AS VARCHAR(256)) = '1'
    C'est parfaitement imbécile et empeche toute optimisation même si un index est posé sur la colonne, car le prédicat ne devient plus "sargable"...
    3) des prédicats connectés par l'opérateur OR ne sont pas, par nature, optimisable (non "sargable").
    4) le LIKE '%motif%' c'est jamais "sargable", sauf à construire un index textuel initiant des index rotatifs
    5) il ne sert à rien de mettre plusieurs parenthèses sur un même prédicat
    6) évitez la clause de tri si vous voulez un résultat rapide. Le tri est l'une des opération les plus couteuse.
    7) Utilisez le CASE ou NULLIF plutôt que le IF. IF n'existe pas dans le langage SQL. C'est une fantaisie de votre SGBDR sans doute !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    SELECT DISTINCT p.products_image, m.manufacturers_id, p.products_id, 
           pd.products_name, p.products_price, p.products_tax_class_id, 
           NULLIF(s.STATUS, s.specials_new_products_price) AS specials_new_products_price, 
           CASE WHEN s.STATUS = s.specials_new_products_price THEN p.products_price END AS final_price
    FROM   products p
           LEFT OUTER JOIN manufacturers m
                USING ( manufacturers_id ) 
           LEFT OUTER JOIN specials s 
                ON p.products_id = s.products_id
           INNER JOIN products_description pd
                ON p.products_id = pd.products_id
           INNER JOIN products_to_categories p2c
                ON p.products_id = p2c.products_id
           INNER JOIN categories c
                ON p2c.categories_id = c.categories_id
    WHERE p.products_status = 1
    AND   pd.language_id = 4
    AND  (pd.products_name LIKE '%a%'
          OR p.products_model LIKE '%a%'
          OR m.manufacturers_name LIKE '%a%')
    CONCLUSION :
    Commencez par apprendre le SQL et faire de belles requêtes (mon site web, comme mes bouquins peuvent vous y aider). Un moteur SQL sait tirer partie de requêtes pour les travailler de façon optimale, à condition qu'elles soient bien écrites.
    Regardez si des index ont été posés au moins pour tout ce qui est clef : primaire (normalement automatique) et clefs étrangères (a faire manuellement).

Discussions similaires

  1. Optimisation d'une requete "TOP 5"
    Par gregb34 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 04/05/2006, 18h17
  2. Réponses: 5
    Dernier message: 14/04/2006, 19h58
  3. Optimisation d'une requete récurrente
    Par winzou dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 23/01/2006, 23h07
  4. Optimisation d'une requete specifique
    Par Tchinkatchuk dans le forum Langage SQL
    Réponses: 9
    Dernier message: 16/12/2005, 15h14
  5. optimisation d'une requete de recherche
    Par moog dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 06/04/2005, 17h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo