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

SQL Oracle Discussion :

Optimisation d'une requête


Sujet :

SQL Oracle

  1. #1
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut Optimisation d'une requête
    Bonjour,
    J'aurai besoin d'aide pour l'optimisation d'une requête.

    Table A
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    IdA | IdB
    ---------
     1  | c2
     2  | c1
     3  | f3
     4  | c4
     5  | e4
     6  | c2
     7  | d4
    Table B
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    IdB | a | b 
    ------------
    c2  | 1 | 2
    c1  | 1 | 4
    f3  | 1 | 6
    c4  | 2 | 3
    e4  | 6 | 5
    c2  | 1 | 3
    d4  | 4 | 4
    Comme résultat je souhaiterai donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    IdA | IdB | a | b 
    ------------
     2  | c1  | 1 | 4
     4  | c4  | 2 | 3
    Voici ma requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT *
    FROM TableA A
     JOIN TableB B
     ON A.IdB = B.IdB
     AND IdB like 'c%'
     
    WHERE IdB not in (Select IdB
         FROM TableB
         WHERE a = '1'
         AND b in ('2','3','5'))
    Or je manipule des millions d'enregistrements et je souhaiterai optimiser tout cela.
    J'ai regardé le cours : http://sqlpro.developpez.com/cours/optimiser/#L9
    Et la règle 10 me montre bien comment optimiser le "not in" mais j'avoue ne pas bien saisir le "LEFT OUTER JOIN".
    Même après ce cours http://sqlpro.developpez.com/cours/s...ntures/#LIII-C j'ai quelques doutes quand à la construction de ma requête.
    En effet je bloque avec la condition "AND IdB like 'c%'", comment dois-je agencer tout ça ?

    Merci

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,


    Et plus simplement ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT *
    FROM TableA A
     inner join JOIN TableB B ON A.IdB = B.IdB
    where b.IdB LIKE 'c%' and b.a <> 1 and b.b not in ('2','3','5')

  3. #3
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Points : 1 327
    Points
    1 327
    Par défaut
    Bonjour,

    peux-tu essayer ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM TableA A JOIN TableB B ON (A.IdB = B.IdB AND IdB LIKE 'c%' and a <> 1 and b not in ('2','3','5'))
    EDIT : Devancé again ...

  4. #4
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Merci pour vos réponses mais il me semble cette requête ne me renverrait rien pour mon jeu de test.
    En effet elle excluerait tous les a = 1 et les b = 2,3,5.
    Or je souhaite ici n'exclure que les couples (a,b) tels que (1,2), (1,3) et (1,5). D'où ma sous-requête.
    Je suis actuellement en chomage technique donc je ne peux pas tester

  5. #5
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Points : 1 327
    Points
    1 327
    Par défaut
    Exact !
    Au temps pour moi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM TableA A JOIN TableB B ON (A.IdB = B.IdB AND IdB LIKE 'c%' AND (a <> 1 OR b NOT IN ('2','3','5'))

  6. #6
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Merci beaucoup.
    Comme une andouille j'avais pas pensé au "OR" dans le join !!
    J'attend de pouvoir tester avant de mettre résolu...

  7. #7
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    Attention, les requêtes qu'on te propose ne donnent pas le même résultat que ta requête initiale :
    - Avec idb NOT IN (...), ça exclut tout les idb si un seul remplit la condition de ta sous-requête.
    - En remplaçant la sous-requête par des conditions directes sur tes lignes, tu n'exclut que les occurences de idb qui remplissent ces conditions.

    Côté performances, il faut le plan d'exécution avant tout, ainsi que les volumétries un peu plus précises genre combien de ligne c'est sensé te retourner.

    Quant aux cours d'optimisation de SQLPro, attention, ça dépend du contexte, du SGBD, ...
    La démarche pragmatique (du moins sur Oracle) c'est : lire le plan d'exécution, comprendre pourquoi c'est lent, imaginer comment ça pourrait l'être moins.

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    La solution avec le OR est pourtant identique à la demande initiale (on avait juste oublie les principes de De Morgan! )

  9. #9
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Si tu changes un peu le jeu d'essai pour y ajouter la dernière ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    IdB | a | b 
    ------------
    c2  | 1 | 2
    c1  | 1 | 4
    f3  | 1 | 6
    c4  | 2 | 3
    e4  | 6 | 5
    c2  | 1 | 3
    d4  | 4 | 4
    c2  | 1 | 6
    Alors c2 | 1 | 6 ressortira dans le résultat avec la solution en OR, mais pas avec la solution NOT IN.
    Dans un cas tu appliques le critère direct sur les lignes, dans l'autre c'est plutôt sur des "groupes"

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Oula, passé a côté de ca ...
    Je pensais qu'elle faisait son test sur un id autre.

    Autant pour moi.

  11. #11
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Citation Envoyé par pacmann Voir le message
    Attention, les requêtes qu'on te propose ne donnent pas le même résultat que ta requête initiale :
    - Avec idb NOT IN (...), ça exclut tout les idb si un seul remplit la condition de ta sous-requête.
    - En remplaçant la sous-requête par des conditions directes sur tes lignes, tu n'exclut que les occurences de idb qui remplissent ces conditions.
    Effectivement ma première solution est alors mauvaise .

    Citation Envoyé par pacmann Voir le message
    Côté performances, il faut le plan d'exécution avant tout, ainsi que les volumétries un peu plus précises genre combien de ligne c'est sensé te retourner.
    Malheureusement je ne peux pas tester mes requêtes aujourd'hui --> chomage technique.

    J'avais déjà essayé d'exéctuter un EXPLAIN PLAN mais impossible de modifier le paramètrage qui permettrait son fonctionnement.

    La requête que je vous présente est juste une partie d'une requête. Sinon la requête que je vous met brasse plusieurs millions de lignes et doit en renvoyer moins de 200 000 lignes. Je ne peux pas être plus précise parce qu'en fait cette requête et une autre totalement indépendant doivent renvoyer en tout environ 200 000 lignes, mais je ne connais pas les proportions.

    Sinon merci beaucoup pour tes explications pour le NOT IN, j'avais mal compris son fonctionnement.

  12. #12
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Points : 1 327
    Points
    1 327
    Par défaut
    Fail again, j'avais pas pensé à ça punkoff

  13. #13
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    L'explain plan, c'est important

    Tu le lances avec quel outil ? C'est quoi le paramétrage qui passe pas ?

    Sinon, ça tourne en combien de temps actuellement ?
    200K lignes à retourner, c'est beaucoup... mais peut être que passer par un index pourrait te faire du bien

    Si j'ai bien compris, ta version NOT IN était fausse au départ ? Dans ce cas si ça se trouve, sans le NOT IN ça passera tout seul

  14. #14
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    J'ai réussi à lancer ma requête sur la prod pendant la pause repas et actuellement ma requête met dans les 45 minutes, j'optimise à mort mais franchement je vois pas d'amélioration notables.
    D'un autre côté c'est normal, la requête complete utilise 6 tables de chacune plusieurs millions de ligne.
    Après je n'ai pas la possibilité de modifier la base de données pour faire un index, je peux toujours en parler autour de moi.
    Est-ce qu'il existe une méthode pour savoir si des index existent déjà ?

    J'utilise TOAD et j'avais vu que l'explain plan pouvait bloquer et que pour cela il fallait changer le nom de la table cible dans le paramétrage TOAD (or ça je peux pas le faire). Je vais essayer de retrouver le lien.

    Pour ma version not in, c'était faux effectivement, mais je n'avais pas pu la tester, je pensais que le not in renverrais les Id correspondants à mes conditions et que ça agirrai comme un filtre. J'avoue qu'avec des requêtes à rallonge on peut s'y perdre

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Mais c'est quoi le plan d'execution de votre requête ?

    Pour les indexs dans toad vous pouvez les voir en faisant une description de vos tables.

    Sinon vous avez aussi la vue user_indexes.


    Dans un premier lieu vérifiez que vous avez des index sur chacuen de vos jointures, après il faudra peut-être couvrir les restrictions dans la clause "where".

    Quel est l'utilité d'extraire 200k lignes ? vous allez faire quel type de traitement avec ?

  16. #16
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Citation Envoyé par punkoff Voir le message
    Mais c'est quoi le plan d'execution de votre requête ?
    Pour l'instant je n'ai plus accès à mes bases de recette et hors de question d'aller sur la prod en horaires administratives. Dès que je peux je m'y remet.

    Citation Envoyé par punkoff Voir le message
    Quel est l'utilité d'extraire 200k lignes ? vous allez faire quel type de traitement avec ?
    Ceci malheureusement n'est pas de mon ressort, je sais que je dois sortir les enregistrements vérifiants un certain nombre de critères pour lancer des traitements dessus par la suite.

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 251
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 251
    Points : 12 903
    Points
    12 903
    Par défaut
    Bonjour,
    Et avec une jointure externe, est-ce que ça va plus vite ?
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT *
    FROM TableA A
     JOIN TableB B
     ON A.IdB = B.IdB
     AND b.IdB LIKE 'c%'
     left outer join TableB as C on C.idb = b.idb and C.a = '1' and C.b in ('2','3','5')
    WHERE C.idb is null

    Tatayo.

  18. #18
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Nouvelle formulation de la requête par les demandeurs :
    Jeu de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    IdA | IdB 
    ----------
     1  | c2  
     1  | c1  
     2  | f3  
     3  | c4  
     3  | e4  
     3  | c5  
     4  | d4
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     IdB | a | b 
    -------------
     c2  | 1 | 2
     c1  | 1 | 4
     f3  | 1 | 6
     c4  | 2 | 3
     e4  | 6 | 5
     c5  | 1 | 4
     d4  | 4 | 4
    Résultat souhaité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    IdA | IdB | a | b 
    ------------------
     3  | c4  | 2 | 3
     3  | c5  | 1 | 4
    Je dois retourner seulement les IdA qui respectent ces conditions pour tous leurs IdB.
    (on voit bien la différence avec IdA = 1 qui ne les respectent pas, on ne renvoi pas la ligne suivante)

    Voici ma nouvelle requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT *
    FROM TableA A
     JOIN (SELECT idB, a, b
       FROM TableB
       WHERE IdB like 'c%'
       AND (a <> 1 OR b not in (2,3,5))) B
     ON A.IdB = B.IdB
    J'ai pas pu la tester (encore). Pensez-vous qu'il est possible de l'optimiser ?
    Perso j'ai vraiment du mal, rien que la construction de la requête correcte est pas facile (difficulté de communication/compréhension des demandes).

  19. #19
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Bonjour,
    Et avec une jointure externe, est-ce que ça va plus vite ?

    Code SQL :
    SELECT
    FROM TableA A
    JOIN TableB B
    ON A.IdB = B.IdB
    AND b.IdB LIKE 'c%'
    LEFT OUTER JOIN TableB AS C ON C.idb = b.idb AND C.a = '1' AND C.b IN ('2','3','5'
    WHERE C.idb IS null
    Malheureusement pour le moment je ne peux toujours pas tester.
    Par contre je veux bien que tu m'explique pourquoi tu met "IdB IS NULL".

  20. #20
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Est-il possible d'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND (a <> 1 OR b not in (2,3,5))
    sous la forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND NOT (a = 1 AND b in (2,3,5))
    J'ai pas réussi à trouver et comme je peux rien tester

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Optimisation d'une requête
    Par Louis-Guillaume Morand dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 20/12/2005, 18h21
  2. Optimisation d'une requête d'insertion
    Par fdraven dans le forum Oracle
    Réponses: 15
    Dernier message: 01/12/2005, 14h00
  3. Optimisation d'une requête patchwork
    Par ARRG dans le forum Langage SQL
    Réponses: 1
    Dernier message: 11/09/2005, 15h23
  4. optimisation d'une requête avec jointure
    Par champijulie dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 07/07/2005, 09h45
  5. [DB2] Optimisation d'une requête
    Par ahoyeau dans le forum DB2
    Réponses: 7
    Dernier message: 11/03/2005, 17h54

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