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 :

Optimiser la vitesse d 'exécution d'une requête


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Autodidacte
    Inscrit en
    Octobre 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autodidacte

    Informations forums :
    Inscription : Octobre 2006
    Messages : 58
    Points : 38
    Points
    38
    Par défaut Optimiser la vitesse d 'exécution d'une requête
    Bonjour,

    je souhaite optimiser ma requête qui est assez lente.

    note : je limite l'affichage a 10 ligne par page mais ça n'améliore guerre la vitesse d'affichage

    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
    SELECT DISTINCT  cbo_emploi.id_emploi, cbo_emploi_cv_contrat.nom AS nom_contrat, cbo_emploi.id_type_poste ,  LEFT(cbo_emploi.code_postal, 2) AS dep, LEFT(cbo_emploi.code_postal, 3) AS dep3, cbo_emploi.ville, cbo_emploi.code_postal, cbo_emploi.pays, cbo_emploi.date, cbo_emploi.date_modif,  cbo_emploi_type_poste.type_poste, cbo_emploi.verifie, cbo_membres_categories.nom_court AS categorie, cbo_emploi.categorie AS id_categorie, cbo_membres.categorie AS type_annonceur,  cbo_emploi_cv_duree_travail.nom AS temps_de_travail, a_partir_timestamp, fin_periode, cbo_emploi.contrat, base_CP.latitude, base_CP.longitude
     
     
                FROM cbo_emploi
     
                LEFT JOIN cbo_emploi_type_poste ON cbo_emploi_type_poste.id_poste_cat = cbo_emploi.id_type_poste
                LEFT JOIN cbo_emploi_cv_contrat ON cbo_emploi_cv_contrat.id=cbo_emploi.contrat
             LEFT JOIN  cbo_membres_categories ON cbo_membres_categories.id= cbo_emploi.categorie
             LEFT JOIN cbo_membres ON cbo_membres.id= cbo_emploi.id_mb_annonceur
             LEFT JOIN cbo_emploi_cv_duree_travail ON cbo_emploi_cv_duree_travail.id=cbo_emploi.duree_travail
     
             LEFT JOIN base_CP
      ON base_CP.INSEE = cbo_emploi.code_ville_insee
     AND base_CP.Libelle_acheminement = cbo_emploi.ville
     AND base_CP.Code_postal = cbo_emploi.code_postal
     
    			 WHERE   cbo_emploi.id_rub='10'  AND  ( verifie = 1 OR verifie = 2 )
    note la table base_CP contient le jeu de donnée de laposte : https://www.data.gouv.fr/fr/datasets...codes-postaux/

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    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 080
    Points : 30 786
    Points
    30 786
    Par défaut
    Y a-t-il des index sur ces tables ? Si oui, sur quelles colonnes ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Autodidacte
    Inscrit en
    Octobre 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autodidacte

    Informations forums :
    Inscription : Octobre 2006
    Messages : 58
    Points : 38
    Points
    38
    Par défaut
    Bonsoir,


    voici mes structures de table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE `base_CP` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `INSEE` varchar(18) DEFAULT NULL,
      `Nom_commune` varchar(38) DEFAULT NULL,
      `Code_postal` varchar(11) DEFAULT NULL,
      `Libelle_acheminement` varchar(32) DEFAULT NULL,
      `Ligne_5` varchar(33) DEFAULT NULL,
      `latitude` varchar(30) NOT NULL,
      `longitude` varchar(30) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=49825 DEFAULT CHARSET=utf8
    Et voici mes index de la table cbo_emploi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ` (
     
      PRIMARY KEY (`id_emploi`),
      UNIQUE KEY `id_emploi` (`id_emploi`),
      KEY `code_postal` (`code_postal`),
      KEY `contact` (`contact`),
      KEY `date` (`date`),
      KEY `email` (`email`),
      KEY `tel` (`tel`),
      KEY `titre` (`id_type_poste`),
      KEY `ville` (`ville`)
    ) ENGINE=MyISAM AUTO_INCREMENT=4515 DEFAULT CHARSET=latin1

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    il faut communiquer les index de chacune des tables de votre requête

    De plus, pourquoi avoir utilisé du varchar pour des attributs comme le code insee et le code postal ?!?
    L'un comme l'autre devraient être de type char(5) vous y gagnerez déjà un poil en perfs, surtout que vous avez défini des index sur ces colonnes !

    De même pour latitude et longitude, là vous n'avez pas d'index, mais le typage est aberrant.
    Ce n'est pas pour rien que les SGBD proposent plusieurs types de données, il faut s'en servir

  5. #5
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Idéalement il faudrait créer dans la table CBO_EMPLOI une colonne ID_BASE_CP et la clé étrangère associée qui référencera la colonne BASE_CP(ID).
    C'est ce qui sera le plus performant pour accéder à la table BASE_CP.

    En attendant vous pouvez créer l'index sur le triplet BASE_CP (base_CP.INSEE, base_CP.Libelle_acheminement, base_CP.Code_postal), mais l'accès sera moins performant qu'avec une clé.

    Comme mentionné par escartefigue je pense que vous avez un peu loupé le copier/coller des infos de toutes les tables.

    Vérifier si vous avez un index sur CBO_EMPLOI.ID_RUB et vérifier son type de données, si c'est un entier supprimé les quotes autour de 10.

  6. #6
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 053
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 053
    Points : 9 392
    Points
    9 392
    Par défaut
    Décompose, avance par étapes.

    Essaie cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT DISTINCT  cbo_emploi.id_emploi, cbo_emploi_cv_contrat.nom AS nom_contrat, cbo_emploi.id_type_poste , 
        LEFT(cbo_emploi.code_postal, 2) AS dep, LEFT(cbo_emploi.code_postal, 3) AS dep3, cbo_emploi.ville, cbo_emploi.code_postal, cbo_emploi.pays, 
        cbo_emploi.date, cbo_emploi.date_modif,  cbo_emploi_type_poste.type_poste, cbo_emploi.verifie, 
     
        cbo_emploi.categorie AS id_categorie,  
        cbo_emploi.contrat 
     
    FROM cbo_emploi
         LEFT JOIN cbo_emploi_type_poste ON cbo_emploi_type_poste.id_poste_cat = cbo_emploi.id_type_poste
     
    WHERE   cbo_emploi.id_rub='10'  AND  ( verifie = 1 OR verifie = 2 )
    Puis celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT DISTINCT  cbo_emploi.id_emploi, cbo_emploi_cv_contrat.nom AS nom_contrat, cbo_emploi.id_type_poste , 
        LEFT(cbo_emploi.code_postal, 2) AS dep, LEFT(cbo_emploi.code_postal, 3) AS dep3, cbo_emploi.ville, cbo_emploi.code_postal, cbo_emploi.pays, 
        cbo_emploi.date, cbo_emploi.date_modif,  cbo_emploi_type_poste.type_poste, cbo_emploi.verifie, 
        cbo_membres_categories.nom_court AS categorie, 
        cbo_emploi.categorie AS id_categorie, cbo_membres.categorie AS type_annonceur, 
        a_partir_timestamp, fin_periode, cbo_emploi.contrat, 
        base_CP.latitude, base_CP.longitude
     
    FROM cbo_emploi
         LEFT JOIN cbo_emploi_type_poste ON cbo_emploi_type_poste.id_poste_cat = cbo_emploi.id_type_poste
         LEFT JOIN cbo_emploi_cv_contrat ON cbo_emploi_cv_contrat.id=cbo_emploi.contrat
         LEFT JOIN  cbo_membres_categories ON cbo_membres_categories.id= cbo_emploi.categorie
     
    WHERE   cbo_emploi.id_rub='10'  AND  ( verifie = 1 OR verifie = 2 )
    Etc, etc, en ajoutant une table à chaque fois, et essaie de voir à quel moment les temps de réponse dérapent. Ca te permettra d'identifier la table coupable.

    Par ailleurs, tu as ce "distinct". Distinct est une fonction "compliquée". Sans le distinct, est-ce que les temps de réponse sont corrects ?

    Tu as mis ce "distinct" pour éliminer les doublons, mais c'est du cache-misère. Si tes données étaient correctes, tu n'aurais pas de doublons, tu pourrais te passer de ce "distinct".
    Dans mon expérience, quand des utilisateurs utilisent Distinct dans une requête, 9 fois sur 10, c'est pour masquer une erreur de conception, et clairement, tu es dans ce cas.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

Discussions similaires

  1. Vitesse d'exécution d'une requête
    Par Shiva dans le forum Requêtes
    Réponses: 17
    Dernier message: 05/08/2015, 18h15
  2. Optimisation du temps d'exécution d'une requête
    Par LeNovice dans le forum DB2
    Réponses: 6
    Dernier message: 12/07/2007, 13h47
  3. Réponses: 9
    Dernier message: 20/06/2005, 12h17
  4. Arrêt de l'exécution d'une requête MySQL dans DELPHI.
    Par joelmarc dans le forum Bases de données
    Réponses: 9
    Dernier message: 11/10/2004, 16h11
  5. Affichage du temps d'exécution d'une requête
    Par milka dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 22/03/2004, 17h48

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