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 :

AIdez moi à optimiser cette requete MySQL SVP


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Inscrit en
    Septembre 2005
    Messages
    193
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 193
    Points : 47
    Points
    47
    Par défaut AIdez moi à optimiser cette requete MySQL SVP
    Bonjour à tous,
    Je suis en train de réaliser une requete assez conséquente et je suis arrivé au bout de mes compétences en terme d'optimisation, j'ai tout essayé : WHERE, HAVING , sous requetes imbriquées...:
    Je suis comme meme passer de 5 minutes à 40 secondes puis à 15 secondes puis à 7 et ce sur un Bi Proc XEON...
    Sachant que le client possede un pauvre athlon 1.3...je crains le pire...
    Voila ma requete aidez moi (le MCD ne sera d'aucune utilité, c'est la syntaxe qui n'est pas optimale je pense...)

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    SELECT SQL_CALC_FOUND_ROWS DATE_FORMAT( actions.date_recontact, '%d/%m/%Y' ) AS date_recontact, lignes_etape.resultat, contacts.id_contact, contacts.nom, societes_specifiques.topage, societes_specifiques.score_societe, societes.id_societe, script_etapes.groupe_etape, s_est_deplace, operation_a_effectuer, SUBSTRING( actions.heure_recontact, 1, 5 ) AS heure_recontact, societes.nom, actions.id_action, actions.id_contact, contacts.fonction_autre
    FROM actions
    LEFT JOIN lignes_etape ON actions.resultat = lignes_etape.id_ligne_etape
    INNER JOIN contacts ON actions.id_contact = contacts.id_contact
    AND contacts.plus_dans_la_soc =0
    INNER JOIN contacts_specifiques ON contacts_specifiques.id_contact = contacts.id_contact
    INNER JOIN societes ON contacts.id_societe = societes.id_societe
    INNER JOIN societes_specifiques ON societes_specifiques.id_societe = societes.id_societe
    AND societes_specifiques.id_entite =2
    INNER JOIN script_etapes ON actions.etape = script_etapes.id_script_etape
    INNER JOIN societes_users ON societes_users.id_societe = societes.id_societe
    AND societes_users.id_campagne =1
    WHERE actions.enregistrement_ok =1
    AND actions.sommeil =0###############
     
    AND actions.id_contact
    IN (
     
     
    SELECT A3.id_contact
    FROM actions AS A3
    INNER JOIN script_etapes S1 ON A3.etape = S1.id_script_etape
    WHERE S1.groupe_etape =3
    AND A3.resultat =0
    HAVING 0 = ( 
    SELECT COUNT( * ) 
    FROM actions A4
    INNER JOIN script_etapes ON A4.etape = script_etapes.id_script_etape
    WHERE script_etapes.groupe_etape =3
    AND A4.id_contact = A3.id_contact
    AND A3.id_action <> A3.id_action ) 
     
    )
    AND actions.id_action = (
     
     
    SELECT MAX( id_action ) 
    FROM actions AS A2
    INNER JOIN script_etapes AS S3 ON A2.etape = S3.id_script_etape
    WHERE A2.id_contact = actions.id_contact
    AND S3.groupe_etape =1
     
    )

  2. #2
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    1) je ne sais pas à quoi sert un HAVING sans GROUP BY, je suis surpris qu'un parser laisse passez cela.

    2) j'indenterais mon code

    3) Je remplacerais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    HAVING 0 = ( SELECT COUNT( * ) 
                 FROM actions ...
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AND NOT EXISTS (SELECT *
                    FROM actions ...
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 759
    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 759
    Points : 52 538
    Points
    52 538
    Billets dans le blog
    5
    Par défaut
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    SELECT SQL_CALC_FOUND_ROWS 
           DATE_FORMAT(A.date_recontact, '%d/%m/%Y' ) AS date_recontact,
           LE.resultat, C.id_contact, C.nom, 
           SS.topage, SS.score_societe, 
           S.id_societe, 
           SE.groupe_etape, 
           s_est_deplace, operation_a_effectuer, 
           SUBSTRING(A.heure_recontact, 1, 5 ) AS heure_recontact, 
           S.nom, A.id_action, A.id_contact, C.fonction_autre
     
    FROM   actions A
           LEFT OUTER JOIN lignes_etape LE                  ON A.resultat = LE.id_ligne_etape
           INNER JOIN script_etapes SE                      ON A.etape = SE.id_script_etape
           INNER JOIN contacts C                            ON A.id_contact = C.id_contact
                 INNER JOIN contacts_specifiques CS         ON C.id_contact = CS.id_contact
                 INNER JOIN societes S                      ON C.id_societe = S.id_societe
                       INNER JOIN societes_specifiques SS   ON S.id_societe = SS.id_societe
                       INNER JOIN societes_users SU         ON S.id_societe = SU.id_societe
     
    WHERE  SU.id_campagne = 1
      AND  SS.id_entite = 2
      AND  A.enregistrement_ok = 1
      AND  C.plus_dans_la_soc = 0
      AND  A.sommeil = 0###############
      AND A.id_contact IN (SELECT A3.id_contact
                           FROM   actions AS A3
                                  INNER JOIN script_etapes S1 ON A3.etape = S1.id_script_etape
                           WHERE  S1.groupe_etape = 3
                             AND  A3.resultat = 0
                             AND NOT EXISTS (SELECT 0
                                             FROM   actions A4
                                                    INNER JOIN script_etapes ON A4.etape = script_etapes.id_script_etape
                                             WHERE  script_etapes.groupe_etape =3
                                               AND  A4.id_contact = A3.id_contact
                                               AND  A3.id_action <> A3.id_action)
     
      AND actions.id_action = (SELECT MAX( id_action )
                               FROM   actions AS A2
                                      INNER JOIN script_etapes AS S3 ON A2.etape = S3.id_script_etape
                               WHERE  A2.id_contact = actions.id_contact
                                 AND S3.groupe_etape =1)
    En l'absence de sémantique difficile de faire plus...
    Mais quel est ce truc : "SQL_CALC_FOUND_ROWS" ???

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  4. #4
    Membre du Club
    Inscrit en
    Septembre 2005
    Messages
    193
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 193
    Points : 47
    Points
    47
    Par défaut
    salut le SQL_CALC_FOUND_ROWS est un des goulot d'etranglement de cette requete, helas il est indispensable .
    Il permet de te donner le bon nombre d'enregistrements renvoyés quand tu mets une clause LIMIT...
    Je vais tester avec un NOT EXISTS

  5. #5
    Membre du Club
    Inscrit en
    Septembre 2005
    Messages
    193
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 193
    Points : 47
    Points
    47
    Par défaut
    Citation Envoyé par SQLpro
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    SELECT SQL_CALC_FOUND_ROWS 
           DATE_FORMAT(A.date_recontact, '%d/%m/%Y' ) AS date_recontact,
           LE.resultat, C.id_contact, C.nom, 
           SS.topage, SS.score_societe, 
           S.id_societe, 
           SE.groupe_etape, 
           s_est_deplace, operation_a_effectuer, 
           SUBSTRING(A.heure_recontact, 1, 5 ) AS heure_recontact, 
           S.nom, A.id_action, A.id_contact, C.fonction_autre
     
    FROM   actions A
           LEFT OUTER JOIN lignes_etape LE                  ON A.resultat = LE.id_ligne_etape
           INNER JOIN script_etapes SE                      ON A.etape = SE.id_script_etape
           INNER JOIN contacts C                            ON A.id_contact = C.id_contact
                 INNER JOIN contacts_specifiques CS         ON C.id_contact = CS.id_contact
                 INNER JOIN societes S                      ON C.id_societe = S.id_societe
                       INNER JOIN societes_specifiques SS   ON S.id_societe = SS.id_societe
                       INNER JOIN societes_users SU         ON S.id_societe = SU.id_societe
     
    WHERE  SU.id_campagne = 1
      AND  SS.id_entite = 2
      AND  A.enregistrement_ok = 1
      AND  C.plus_dans_la_soc = 0
      AND  A.sommeil = 0###############
      AND A.id_contact IN (SELECT A3.id_contact
                           FROM   actions AS A3
                                  INNER JOIN script_etapes S1 ON A3.etape = S1.id_script_etape
                           WHERE  S1.groupe_etape = 3
                             AND  A3.resultat = 0
                             AND NOT EXISTS (SELECT 0
                                             FROM   actions A4
                                                    INNER JOIN script_etapes ON A4.etape = script_etapes.id_script_etape
                                             WHERE  script_etapes.groupe_etape =3
                                               AND  A4.id_contact = A3.id_contact
                                               AND  A3.id_action <> A3.id_action)
     
      AND actions.id_action = (SELECT MAX( id_action )
                               FROM   actions AS A2
                                      INNER JOIN script_etapes AS S3 ON A2.etape = S3.id_script_etape
                               WHERE  A2.id_contact = actions.id_contact
                                 AND S3.groupe_etape =1)
    En l'absence de sémantique difficile de faire plus...
    Mais quel est ce truc : "SQL_CALC_FOUND_ROWS" ???

    A +

    Merci sql pro, ca marche grace à toi
    Tu portes bien ton nick

Discussions similaires

  1. comment optimiser cette requete Postgres?
    Par medsine dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 29/05/2008, 14h19
  2. aidez moi pour cette requete
    Par bassoum dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 12/05/2008, 09h51
  3. aidez moi a resoudre ce probleme svp
    Par webisa dans le forum Requêtes
    Réponses: 6
    Dernier message: 29/09/2007, 09h57
  4. Aidez moi pour ma requete sql svp
    Par fadelal dans le forum Langage SQL
    Réponses: 2
    Dernier message: 20/08/2007, 16h11
  5. pouvez vous m'aider a optimiser cette requete
    Par taoufikiory dans le forum SQL
    Réponses: 4
    Dernier message: 20/07/2007, 15h32

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