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

Requêtes MySQL Discussion :

[mysql] Toujours ce problème d'index !!


Sujet :

Requêtes MySQL

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Points : 314
    Points
    314
    Par défaut [mysql] Toujours ce problème d'index !!
    Bonjour à tous,
    Voilà je fais la requête suivante:

    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
     
    SELECT DESCRIPTION
    FROM partenaire
    WHERE UNB
    IN (
     
    SELECT UNB
    FROM message
    WHERE ID_MESSAGE
    IN (
     
    SELECT ID_MESSAGE
    FROM commande
    WHERE NADDP NOT 
    IN (
     
    SELECT NADDP
    FROM compte
    WHERE PAYS = 'NL'
    AND CODE_SUPPLIER = 'M'
    )
    )
    )
    Qui me prend énormément de ressource et de temps, tellement que je suis obligé de l'arrêter !!

    De très bon conseils m'ont été précédemment donné sur le forum mais je crois bien que je n'y arrive pas.
    Je n'arrive pas à utiliser les index que j'ai mis sur mes tables, comme le montre un EXPLAIN de la requête du dessus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    id select_type table type possible_keys key key_len ref rows Extra 
     
    1 PRIMARY partenaire ALL NULL NULL NULL NULL 109 Using where 
     
    2 DEPENDENT SUBQUERY message ALL NULL NULL NULL NULL 4925 Using where 
     
    3 DEPENDENT SUBQUERY commande ALL NULL NULL NULL NULL 18168 Using where 
     
    4 DEPENDENT SUBQUERY compte ref CODE_SUPPLIER,PAYS PAYS 2 const 479 Using where
    Pourtant, j'ai mis les index suivants:
    Sur table compte: PAYS et CODE_SUPPLIER
    Sur table commande: NADDP
    Sur table message: ID_MESSAGE
    Sur table partenaire: UNB

    Voici les show create table des différentes tables:
    * Table compte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE TABLE `compte` (
    `ID_COMPTE` int(6) NOT NULL auto_increment,
    `NADDP` varchar(20) NOT NULL default '',
    `CODE_SUPPLIER` char(1) NOT NULL default '',
    `PAYS` char(2) NOT NULL default '',
    PRIMARY KEY  (`ID_COMPTE`),
    KEY `CODE_SUPPLIER` (`CODE_SUPPLIER`),
    KEY `PAYS` (`PAYS`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1
    * Table commande
    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
     
    CREATE TABLE `commande` (
    `ID_COMMANDE` int(8) NOT NULL auto_increment,
    `ID_MESSAGE` int(6) NOT NULL default '0',
    `BGM` varchar(50) NOT NULL default '-----',
    `DTM137` varchar(15) default NULL,
    `NADBY` varchar(30) default NULL,
    `NADSE` varchar(30) default NULL,
    `NADSU` varchar(30) default NULL,
    `NADDP` varchar(30) default NULL,
    `NBLIGNES` int(4) default NULL,
    `DATE_RECEPTION_DOC` varchar(6) NOT NULL default '',
    `HEURE_RECEPTION_DOC` varchar(6) NOT NULL default '',
    PRIMARY KEY  (`ID_COMMANDE`),
    KEY `NADDP` (`NADDP`),
    KEY `DATE_RECEPTION_DOC` (`DATE_RECEPTION_DOC`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1
    * Table message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    CREATE TABLE `message` (
    `ID_MESSAGE` int(6) NOT NULL auto_increment,
    `UNB` varchar(30) default NULL,
    `UNOA` varchar(30) default NULL,
    `DATE` varchar(15) default NULL,
    `NOM` varchar(20) default NULL,
    `DATECREATION` varchar(20) default NULL,
    `HEURECREATION` varchar(6) default NULL,
    `TAILLE` int(10) default '0',
    PRIMARY KEY  (`ID_MESSAGE`),
    KEY `ID_MESSAGE` (`ID_MESSAGE`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1
    * Table partenaire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CREATE TABLE `partenaire` (
    `UNB` varchar(35) NOT NULL default '',
    `QUALIFIANT` varchar(4) NOT NULL default '',
    `FICHIER_SORTIE` varchar(8) NOT NULL default '',
    `DESCRIPTION` varchar(35) NOT NULL default '',
    PRIMARY KEY  (`UNB`),
    KEY `UNB` (`UNB`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1

    Voilà, j'espère que vous trouverez une solution pour moi. Je pense que je n'ai pas compris quelquechose avec les index.Je suis un peu dans la m... , si vous avez une idée, je suis ultra preneur !!!

    Bonne fin de matinée.
    tout le monde est d'accord pour critiquer la pensée unique

  2. #2
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    J'ai testé de mon côté et cette-fois-ci les index ne sont pas utilisés non plus chez moi
    Ca semble être dû à un bug qui bizarrement n'a pas encore été fixé : http://bugs.mysql.com/bug.php?id=10309

    Donc le mieux c'est encore d'utiliser des jointures à la place des sous-requêtes : cf http://mysql.developpez.com/faq/?pag..._sous_requetes
    Pensez au bouton

  3. #3
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Apparemment l'optimisation des sous-requêtes de ce type ne serait correctement gérée que dans la version 5.1 : http://bugs.mysql.com/bug.php?id=9021
    Pensez au bouton

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Points : 314
    Points
    314
    Par défaut
    ça veut dire que ma requête est correcte alors ???
    Il suffit que j'installe la version 5.1 de mysql ???
    tout le monde est d'accord pour critiquer la pensée unique

  5. #5
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Citation Envoyé par LE NEINDRE
    ça veut dire que ma requête est correcte alors ???
    Oui, tout comme celle que tu avais postée dans le thread précédent.

    Citation Envoyé par LE NEINDRE
    Il suffit que j'installe la version 5.1 de mysql ???
    Ca va être difficile à moins que tu t'introduises dans les machines des développeurs de MySQL AB... elle est en cours de conception et pas dispo avant... longtemps
    Pensez au bouton

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Points : 314
    Points
    314
    Par défaut
    Maximilian, aux vues de l'article que tu écris dans la FAQ sur les remplacements de sous res-requêtes par des jointures, j'ai essayer de transcrire la requête ci-dessous:
    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
     
    SELECT DESCRIPTION 
    FROM partenaire 
    WHERE UNB 
    IN ( 
     
    SELECT UNB 
    FROM message 
    WHERE ID_MESSAGE 
    IN ( 
     
    SELECT ID_MESSAGE 
    FROM commande 
    WHERE NADDP NOT 
    IN ( 
     
    SELECT NADDP 
    FROM compte 
    WHERE PAYS = 'NL' 
    AND CODE_SUPPLIER = 'M' 
    ) 
    ) 
    )
    en utilisant les jointures....

    Mais .... je suis un peu lent, fatigué et je bloque !!



    Pour le début, j'ai écrit ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT distinct part.DESCRIPTION FROM partenaire part, message mess, commande cmd, compte com
    WHERE part.UNB=mess.UNB
    AND mess.ID_MESSAGE=cmd.ID_MESSAGE
    .......
    Déjà, je ne sais même pas si ça veut dire la même chose que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT DESCRIPTION 
    FROM partenaire 
    WHERE UNB 
    IN ( 
     
    SELECT UNB 
    FROM message 
    WHERE ID_MESSAGE 
    IN ( 
    SELECT ID_MESSAGE 
    FROM commande 
    .......
    Est-ce que je suis juste ???

    Ensuite, je ne vois pas du tout comment remplacer mon NOT IN (par le LEFT JOIN) et l'intégrer dans ma requête totale.

    Comment faire ???


    PS: J'ai tester un EXPLAIN de la ma requête avec jointures en remplaçant le NOT IN de fin par un IN (tu me comprends ?) pour voir si les index étaient pris en compte et ça marche je crois, j'obtiens pour la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    EXPLAIN (
    SELECT DISTINCT part.DESCRIPTION
    FROM partenaire part, message mess, commande cmd, compte com
    WHERE part.UNB = mess.UNB
    AND mess.ID_MESSAGE = cmd.ID_MESSAGE
    AND cmd.NADDP = com.NADDP
    )
    le résultat du EXPLAIN suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra  
     
    1 SIMPLE com ALL NULL NULL NULL NULL 1111 Using temporary 
     
    1 SIMPLE cmd ref NADDP,ID_MESSAGE NADDP 31 euredi.com.NADDP 29 Using where 
     
    1 SIMPLE mess eq_ref PRIMARY,ID_MESSAGE PRIMARY 4 euredi.cmd.ID_MESSAGE 1   
     
    1 SIMPLE part ref UNB UNB 35 euredi.mess.UNB 1 Using where
    tout le monde est d'accord pour critiquer la pensée unique

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 23
    Points : 26
    Points
    26
    Par défaut
    La version 5.0 release candidate est dispo maintenant.

  8. #8
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Citation Envoyé par LE NEINDRE
    Ensuite, je ne vois pas du tout comment remplacer mon NOT IN (par le LEFT JOIN) et l'intégrer dans ma requête totale.

    Comment faire ???
    En mettant simplement le LEFT JOIN à la suite des autres jointures :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT partenaire.DESCRIPTION
    FROM partenaire, message, commande LEFT JOIN compte
    ON commande.NADDP = compte.NADDP AND compte.pays='NL' AND compte.code_supplier='M'
    WHERE partenaire.UNB = message.UNB
    AND message.id_message = commande.id_message
    AND compte.NADDP IS NULL
    Ca devrait fonctionner...


    Citation Envoyé par LE NEINDRE
    le résultat du EXPLAIN suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra  
     
    1 SIMPLE com ALL NULL NULL NULL NULL 1111 Using temporary 
     
    1 SIMPLE cmd ref NADDP,ID_MESSAGE NADDP 31 euredi.com.NADDP 29 Using where 
     
    1 SIMPLE mess eq_ref PRIMARY,ID_MESSAGE PRIMARY 4 euredi.cmd.ID_MESSAGE 1   
     
    1 SIMPLE part ref UNB UNB 35 euredi.mess.UNB 1 Using where
    Et quel temps met cette requête à s'exécuter ?
    Pensez au bouton

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Points : 314
    Points
    314
    Par défaut
    Le résultat pour cette requête mets: 0.0601 s
    C'est parfait.
    Merci beaucoup pour ton coups de main.
    Je vais essayer de comprendre ces jointures !!!!
    Fiou, c'est quand même compliqué le SQL .....

    Bonne journée !!
    tout le monde est d'accord pour critiquer la pensée unique

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. MySQL Cluster problème d'index
    Par Oimbart dans le forum Administration
    Réponses: 1
    Dernier message: 24/04/2009, 23h30
  2. Problème d'index avec load data file
    Par bruno782 dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 09/03/2005, 12h11
  3. Optimisations mysql sur les requêtes SELECT: index
    Par leo'z dans le forum Débuter
    Réponses: 2
    Dernier message: 29/11/2003, 13h23
  4. Problème d'index
    Par claude dans le forum SQL
    Réponses: 6
    Dernier message: 04/08/2003, 15h55
  5. Toujours un problème de rafraichissement de DBGrid
    Par tripper.dim dans le forum C++Builder
    Réponses: 4
    Dernier message: 09/12/2002, 13h15

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