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 :

[Optim] Requête avec jointures et max


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de GyZmoO
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 428
    Par défaut [Optim] Requête avec jointures et max
    Bonjour à tous.

    Je me tourne vers vous, car j'ai une requête qui "mouline" bien trop longtemps..

    Voici la requête en question :

    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
     
    EXPLAIN SELECT * FROM T_TRACE st
    INNER JOIN T_MEASUREMENT_CHAIN mc ON mc.CHAIN_ID = st.CHAIN_ID
    INNER JOIN T_SITE si ON si.SITE_ID = mc.SITE_ID
    INNER JOIN T_ENTITY tr ON tr.XPDR_ID = st.XPDR_ID
     
    WHERE
    tr.XPDR_ID = 1
    and (st.TRACE_TYPE = 'myType')
    and (st.TRACE_ANSWER_TYPE = 0
          or st.TRACE_ANSWER_TYPE = 4
          or st.TRACE_ANSWER_TYPE = 3
          or st.TRACE_ANSWER_TYPE = 5)
    and (si.SITE_NAME = 'Paris')
    and (mc.CHAIN_NAME = 'myChain')
    and st.TRACE_MEASURE_DATE =
     
    (SELECT MAX(TRACE_MEASURE_DATE) FROM T_TRACE st
    INNER JOIN T_MEASUREMENT_CHAIN mc ON mc.CHAIN_ID = st.CHAIN_ID
    INNER JOIN T_SITE si ON si.SITE_ID = mc.SITE_ID
    INNER JOIN T_ENTITY tr ON tr.XPDR_ID = st.XPDR_ID
    WHERE
    tr.XPDR_ID = 1
    and (st.TRACE_TYPE = 'myType')
    and (st.TRACE_ANSWER_TYPE = 0
          or st.TRACE_ANSWER_TYPE = 4
          or st.TRACE_ANSWER_TYPE = 3
          or st.TRACE_ANSWER_TYPE = 5)
    and (si.SITE_NAME = 'Paris')
    and (mc.CHAIN_NAME = 'myChain')
    Donc pour parler plus clairement je voudrais récupérer toutes les lignes de la table T_TRACE qui correspondent a divers paramètres (nom du site, nom de la chain, nom de entity) --> Je récupère donc un paquet de ligne, et parmi celles ci, je voudrais celle qui a la date la plus récente (la sous requête avec MAX...)

    Je précise que cette requête fonctionne, i.e elle me retourne le résultat attendu, mais j'ai le temps d'aller chercher un café et de le boire avant qu'elle me le donne..

    Je précise également, que toutes les colonnes intervenant dans les jointures sont indexées.

    Enfin, j'avais essayé avec un "ORDER BY TRACE_MEASURE_DATE DESC LIMIT 1" à la place de la sous requête, et c'était pas mieux...

    Si qq'un peut me donner des billes, ça serait bien cool !

  2. #2
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    Saluton,
    Pour la lisibilité je remplacerais
    Code mysql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    AND (st.TRACE_ANSWER_TYPE = 0
          OR st.TRACE_ANSWER_TYPE = 4
          OR st.TRACE_ANSWER_TYPE = 3
          OR st.TRACE_ANSWER_TYPE = 5)
    par
    Code mysql : Sélectionner tout - Visualiser dans une fenêtre à part
    AND (st.TRACE_ANSWER IN (0,3,4,5)
    .
    Pour le reste, MySQL apprécie assez peu les sous-requêtes.
    J'ajoute que la guerre des étoiles est parfois aussi très consommatrice de ressources.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  3. #3
    Membre éclairé Avatar de GyZmoO
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 428
    Par défaut
    Yop merci pour la réponse.
    Ok pour le IN, c'est plus lisible.

    Pour la guerre des étoiles pas de prob, je sais J'ai juste mis ça en recopiant la requête pour tester (sinon dans le code, y'a juste les colonnes nécessaires ^^)

  4. #4
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Justement, si tu donnais le vrai SELECT et la structure des tables, j'aurais peut-être une solution avec une jointure simple sur une sous-requête GROUP BY.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Membre éclairé Avatar de GyZmoO
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 428
    Par défaut
    Bonjour !

    Voici le select :

    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
     
    EXPLAIN SELECT st.TRACE_ID, st.TRACE_VAL, st.XPDR_ID, st.TRACE_TYPE, st.TRACE_ANSWER_TYPE, st.TRACE_USER  FROM T_TRACE st
    INNER JOIN T_MEASUREMENT_CHAIN mc ON mc.CHAIN_ID = st.CHAIN_ID
    INNER JOIN T_SITE si ON si.SITE_ID = mc.SITE_ID
    INNER JOIN T_ENTITY tr ON tr.XPDR_ID = st.XPDR_ID
     
    WHERE
    tr.XPDR_ID = 1
    AND (st.TRACE_TYPE = 'myType')
    AND (st.TRACE_ANSWER_TYPE = 0
          OR st.TRACE_ANSWER_TYPE = 4
          OR st.TRACE_ANSWER_TYPE = 3
          OR st.TRACE_ANSWER_TYPE = 5)
    AND (si.SITE_NAME = 'Paris')
    AND (mc.CHAIN_NAME = 'myChain')
    AND st.TRACE_MEASURE_DATE =
     
    (SELECT MAX(TRACE_MEASURE_DATE) FROM T_TRACE st
    INNER JOIN T_MEASUREMENT_CHAIN mc ON mc.CHAIN_ID = st.CHAIN_ID
    INNER JOIN T_SITE si ON si.SITE_ID = mc.SITE_ID
    INNER JOIN T_ENTITY tr ON tr.XPDR_ID = st.XPDR_ID
    WHERE
    tr.XPDR_ID = 1
    AND (st.TRACE_TYPE = 'myType')
    AND (st.TRACE_ANSWER_TYPE IN (0,3,4,5))
    AND (si.SITE_NAME = 'Paris')
    AND (mc.CHAIN_NAME = 'myChain')

  6. #6
    Membre éclairé Avatar de GyZmoO
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 428
    Par défaut
    La table T_TRACE :

    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
     
    CREATE TABLE `t_trace` (
      `TRACE_ID` int(11) NOT NULL AUTO_INCREMENT,
      `TRACE_MEASURE_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      `TRACE_TYPE` enum('Spect', 'Statistics', 'Inside', 'Outside') DEFAULT NULL,
      `TRACE_USER` varchar(40) DEFAULT NULL,
      `TRACE_CENTER_FREQ` decimal(15,6) NOT NULL,
      `TRACE_BANDWIDTH` decimal(15,6) NOT NULL,
      `TRACE_RBW` decimal(15,6) NOT NULL,
      `TRACE_VBW` decimal(15,6) NOT NULL,
      `TRACE_VBW_AUTO` tinyint(1) NOT NULL,
      `TRACE_RBW_AUTO` tinyint(1) NOT NULL,
      `TRACE_REF_LEVEL` float NOT NULL DEFAULT '-20',
      `TRACE_NB_DB_DIV` float NOT NULL DEFAULT '10',
      `TRACE_TOTAL_POWER` float NOT NULL,
      `TRACE_TOTAL_EIRP` float NOT NULL,
      `TRACE_X_THRESHOLD` mediumtext,
      `TRACE_Y_THRESHOLD` mediumtext,
      `TRACE_TRACE_TYPE` int(11) NOT NULL,
      `TRACE_TRACE_COUNT` int(11) NOT NULL,
      `TRACE_Y_VAL` mediumblob,
      `TRACE_XPOL_ID` int(11) NOT NULL,
      `LINKED_SPECTRUM_ID` int(11) NOT NULL,
      `TRACE_ANSWER_TYPE` tinyint(1) NOT NULL,
      `TRACE_IS_REFERENCE` tinyint(1) NOT NULL,
      `XPDR_ID` smallint(6) DEFAULT NULL,
      `RF_ID` smallint(6) DEFAULT NULL,
      `CHAIN_ID` smallint(6) DEFAULT NULL,
      PRIMARY KEY (`TRACE_ID`),
      KEY `IND_SPECT_DATE` (`TRACE_MEASURE_DATE`,`TRACE_TYPE`),
      KEY `IND_SPECT_XPDR_MEAS_DATE` (`XPDR_ID`,`TRACE_MEASURE_DATE`),
      KEY `IND_SPECT_CHAIN_MEAS_DATE` (`CHAIN_ID`,`TRACE_MEASURE_DATE`)
    ) ENGINE=InnoDB AUTO_INCREMENT=193298 DEFAULT CHARSET=utf8
    /*!50100 PARTITION BY RANGE (TRACE_ID)
    (PARTITION p201136 VALUES LESS THAN (288822) ENGINE = InnoDB,
     PARTITION pLast VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
    Comme vous pouvez le voir il n'y a pas de FK, car la table est partitionnée.

    La table T_MEASUREMENT_CHAIN

    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 `t_measurement_chain` (
      `CHAIN_ID` smallint(6) NOT NULL AUTO_INCREMENT,
      `SITE_ID` smallint(6) NOT NULL,
      `CHAIN_NAME` varchar(40) NOT NULL,
      `CHAIN_MANUFACTURER` varchar(40) DEFAULT NULL,
      `CHAIN_MODEL` varchar(40) DEFAULT NULL,
      `CHAIN_TYPE` tinyint(4) NOT NULL,
      `CHAIN_ACTIVE` tinyint(1) NOT NULL,
      `CHAIN_UNWANTED_MAX_BAND` decimal(15,6) DEFAULT NULL,
      `CHAIN_MAX_SPAN` float DEFAULT NULL,
      `CHAIN_TV_TYPE` tinyint(1) NOT NULL,
      `CHAIN_NB_PORTS` int(11) DEFAULT NULL,
      PRIMARY KEY (`CHAIN_ID`),
      KEY `fk_measchain_sitename` (`SITE_ID`),
      CONSTRAINT `fk_measchain_sitename` FOREIGN KEY (`SITE_ID`) REFERENCES `t_site` (`SITE_ID`)
    ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
    La table T_SITE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE TABLE `t_site` (
      `SITE_ID` smallint(6) NOT NULL AUTO_INCREMENT,
      `SITE_NAME` varchar(40) NOT NULL,
      `SITE_TCP_ADDRESS` varchar(20) NOT NULL,
      `SITE_TYPE` tinyint(4) NOT NULL,
      `SITE_LAST_DATA_AUTO_ARCHIVE` datetime DEFAULT NULL,
      `SITE_LAST_RESULT_AUTO_ARCHIVE` datetime DEFAULT NULL,
      PRIMARY KEY (`SITE_ID`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
    Et enfin T_ENTITY :

    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
     
    CREATE TABLE `t_entity` (
      `XPDR_ID` smallint(6) NOT NULL AUTO_INCREMENT,
      `SAT_ID` smallint(6) NOT NULL,
      `XPDR_NAME` varchar(40) NOT NULL,
      `XPDR_LABEL_NAME` varchar(40) NOT NULL,
      `EXTERNAL_XPDR_NAME` varchar(40) NOT NULL,
      `XPDR_COMMENT` varchar(255) DEFAULT NULL,
      `XPDR_LAST_UPDATE` timestamp NULL DEFAULT NULL,
      `XPDR_GLOBAL_POLICY` tinyint(4) NOT NULL,
      `XPDR_TYPE` int(11) NOT NULL,
      `RF_ID` smallint(6) DEFAULT NULL,
      `CUST_ID` smallint(6) DEFAULT NULL,
      `BEAM_ID` smallint(6) NOT NULL,
      `SPECT_ID` int(11) DEFAULT NULL,
      `UPXPDR_ID` smallint(6) DEFAULT NULL,
      `XPDR_STATUS` tinyint(4) NOT NULL DEFAULT '2',
      `XPDR_LAST_SYNCHRO_DATE` timestamp NULL DEFAULT NULL,
      PRIMARY KEY (`XPDR_ID`),
      KEY `fk_xpdr_uplinkxpdr` (`UPXPDR_ID`),
      KEY `fk_xpdr_beam` (`BEAM_ID`),
      KEY `fk_xpdr_custid` (`CUST_ID`),
      KEY `fk_xpdr_rfpath` (`RF_ID`),
      KEY `fk_xpdr_satcode` (`SAT_ID`),
      KEY `IND_XPDR` (`XPDR_NAME`,`SAT_ID`,`XPDR_TYPE`),
      CONSTRAINT `fk_xpdr_beam` FOREIGN KEY (`BEAM_ID`) REFERENCES `t_beam` (`BEAM_ID`),
      CONSTRAINT `fk_xpdr_custid` FOREIGN KEY (`CUST_ID`) REFERENCES `t_customer` (`CUST_ID`),
      CONSTRAINT `fk_xpdr_rfpath` FOREIGN KEY (`RF_ID`) REFERENCES `t_rfp` (`RF_ID`),
      CONSTRAINT `fk_xpdr_satcode` FOREIGN KEY (`SAT_ID`) REFERENCES `t_sata` (`SAT_ID`),
      CONSTRAINT `fk_xpdr_uplinkxpdr` FOREIGN KEY (`UPXPDR_ID`) REFERENCES `t_entity` (`XPDR_ID`)
    ) ENGINE=InnoDB AUTO_INCREMENT=827 DEFAULT CHARSET=utf8

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

Discussions similaires

  1. Requête avec jointure et Max(date)
    Par Augustule dans le forum Requêtes
    Réponses: 2
    Dernier message: 14/01/2014, 23h05
  2. optimisation d'une requête avec jointure
    Par champijulie dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 07/07/2005, 09h45
  3. Requête avec jointures
    Par Corben dans le forum Langage SQL
    Réponses: 4
    Dernier message: 16/11/2004, 12h55
  4. Mise à jour de table impossible après requête avec jointure
    Par sto dans le forum Bases de données
    Réponses: 5
    Dernier message: 17/03/2004, 13h24
  5. problème de requête avec jointures
    Par tinhat dans le forum Requêtes
    Réponses: 7
    Dernier message: 11/08/2003, 10h33

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