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 de requête et index


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 134
    Points : 77
    Points
    77
    Par défaut Optimisation de requête et index
    Bonjour,
    Je me retrouve avec ce genre de requête que je dois optimiser:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * FROM T WHERE c1 = 5448 AND c2 = 2 AND c3 IN (541784,69854,515074, ...)
    le IN du c3 contient plusieurs milliers d'entrées.

    Pour le moment j'ai l'index suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CREATE INDEX IDX_T on T (c3,c1,c2)
    L'index commence par la colonne du IN donc.

    Mais la requête prend encore trop de temps.

    Je me demandais si il ne serait mieux de créér un index de ce genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CREATE INDEX IDX_T on T (c1,c2,c3)
    Donc en mettant la colonne du IN à la fin de l'index.
    Je suis également à l'écoute d'éventuelles autres idées qui pourrait optimiser cette requête.

    Je précise que je ne peux pas trop tester car je ne suis pas admin de la base.

  2. #2
    En attente de confirmation mail
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Octobre 2010
    Messages
    501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2010
    Messages : 501
    Points : 1 060
    Points
    1 060
    Par défaut
    De quel SGBD s'agit-il ?
    L'optimisation d'un code SQL dépend beaucoup du SGBD.
    Plusieurs pistes d'amélioration sont envisageable.

    Par ailleurs, ne pas avoir les droits admin sur une base n'empêche pas en générale d'utiliser des tables temporaires et de les indexer.

  3. #3
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    D'où provient cette liste de plusieurs milliers de nombres ?

    L'idéal serait de faire une table, fut-elle temporaire, contenant en une seule colonne tous ces nombres à rechercher, d'indexer cette colonne puis de faire une jointure avec la table temporaire.

    Si cette solution est impossible, dans la mesure où il y a un index sur c3, peut-être qu'en triant la liste dans l'ordre ascendant accélérerait un peu les choses.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    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 !

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 134
    Points : 77
    Points
    77
    Par défaut
    De quel SGBD s'agit-il ?
    Il s'agit de DB2.

    D'où provient cette liste de plusieurs milliers de nombres ?

    L'idéal serait de faire une table, fut-elle temporaire, contenant en une seule colonne tous ces nombres à rechercher, d'indexer cette colonne puis de faire une jointure avec la table temporaire.

    Si cette solution est impossible, dans la mesure où il y a un index sur c3, peut-être qu'en triant la liste dans l'ordre ascendant accélérerait un peu les choses.
    C'est une liste renvoyée par une fonction java.
    Cette fonction construit la liste à partir d'une requête SQL.
    J'ai bien essayé d'injecter cette requête dans la requête principale en faisant quelque chose de ce genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM T WHERE c1 = 5448 AND c2 = 2 AND c3 IN (SELECT id from T2 where ...)
    Mais au final c'est encore plus lent.
    Je vais essayer de trier au préalable cette liste, ça me parait pas bête comme idée. Je vous tiens au courant lundi.

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    Tu as besoin d'apprendre le SQL, et notamment les jointures !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT * 
    FROM T 
    INNER JOIN T2 ON T2.id = t.c3
    WHERE c1 = 5448 
      AND c2 = 2
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    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 !

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Sinon, pour la question initial le 2eme index devrait mieux gérer la situation.

    Simplement car tu aurai une sélectivité beaucoup plus réduite pour traiter ta clause IN.

    Après reste à voir ton select, car avec un "select *" DB2 pourra partir sur un scanage de table direct s'il évalue que tu vas ramener plus de 15-20% des enregistrement totale de ta table.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 134
    Points : 77
    Points
    77
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Tu as besoin d'apprendre le SQL, et notamment les jointures !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT * 
    FROM T 
    INNER JOIN T2 ON T2.id = t.c3
    WHERE c1 = 5448 
      AND c2 = 2
    OK mais au final, le plan de requête est le même non?
    Il va devoir passer en revue tous les c3 qui sont dans la table/liste.

    Citation Envoyé par punkoff Voir le message
    Sinon, pour la question initial le 2eme index devrait mieux gérer la situation.

    Simplement car tu aurai une sélectivité beaucoup plus réduite pour traiter ta clause IN.

    Après reste à voir ton select, car avec un "select *" DB2 pourra partir sur un scanage de table direct s'il évalue que tu vas ramener plus de 15-20% des enregistrement totale de ta table.
    C'est aussi ce que je me suis dis. Je vais donc tenter ça. Merci.
    Sinon il y a peu de chance que ca me renvoie plus de 1% de la table.
    Mais je ne vois pas trop pour quelle raison il se mettrait à faire un scannage complet.

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par Hypnocrate Voir le message
    OK mais au final, le plan de requête est le même non?
    Il va devoir passer en revue tous les c3 qui sont dans la table/liste.
    Sauf que la jointure est l'opération la plus optimisée dans un SGBD et ce sera beaucoup plus rapide de faire en une requête et une seule transaction entre l'application et le SGBD que de faire une requête, une liste en java et une autre requête pour comparer à la liste, laquelle est longue.

    Ne pas essayer de faire faire à un langage de programmation ce qui est le boulot du SGBD !

    Et bien sûr, pour que la requête soit exécutée rapidement, il faut que les tables soient correctement indexées.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    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 !

Discussions similaires

  1. Requête SQL optimisée sur table d'index
    Par mill3d dans le forum Requêtes et SQL.
    Réponses: 13
    Dernier message: 25/08/2010, 13h05
  2. Positionnement d'index pour optimiser une requête
    Par Monstros Velu dans le forum Développement
    Réponses: 14
    Dernier message: 17/02/2010, 17h53
  3. Optimisation de requête, quel index ?
    Par compu dans le forum Requêtes
    Réponses: 4
    Dernier message: 23/10/2008, 01h07
  4. [Access] Optimisation performance requête - Index
    Par fdraven dans le forum Access
    Réponses: 11
    Dernier message: 12/08/2005, 15h30
  5. Optimisations mysql sur les requêtes SELECT: index
    Par leo'z dans le forum Débuter
    Réponses: 2
    Dernier message: 29/11/2003, 14h23

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