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 :

Question sur un plan d'exécution


Sujet :

SQL Oracle

  1. #1
    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 Question sur un plan d'exécution
    Bonjour !

    Ma requête : (retouchée pour garder l'anonymat )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT *
    FROM MaTable A JOIN MaTable B
      ON a.id_compte = b.id_compte
     AND a.etat = b.etat
    WHERE a.id_compte = (SELECT id_compte FROM TableRef C WHERE nom_compte = 'X')
    ORDER BY a.unchamp
    Donne le plan d'exécution suivant :
    SELECT STATEMENT 1 142 179K
    SORT ORDER BY 1 142 179K
    HASH JOIN 1 142 179K
    TABLE ACCESS BY INDEX ROWID MaTable 3802 193K 1104
    INDEX RANGE SCAN IndexTable1 15209 79
    TABLE ACCESS BY INDEX ROWID TableRef 1 33 2
    INDEX UNIQUE SCAN IndexRef1 1 1
    TABLE ACCESS FULL MaTable 1897K 162M 178K
    C'est pas très lisible, mais l'important est de voir que le CBO choisit FTS alors que ça aurait été sympa de lire IndexTable1...

    Ce qu'il faut noter, c'est que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (SELECT id_compte FROM TableRef C WHERE nom_compte = 'X')
    Renvoie une seule ligne. (y'a un index unique)

    Maintenant, si on substitue directement la valeur, ça donne la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT *
    FROM MaTable A JOIN MaTable B
      ON a.id_compte = b.id_compte
     AND a.etat = b.etat
    WHERE a.id_compte = 378
    ORDER BY a.unchamp
    Et là, le plan correspondant est :
    0 SELECT STATEMENT 1 142 2217
    1 SORT ORDER BY 1 142 2217
    2 HASH JOIN 1 142 2211
    3 TABLE ACCESS BY INDEX ROWID MaTable 3802 193K 1104
    4 INDEX RANGE SCAN IndexTable1 15209 79
    5 TABLE ACCESS BY INDEX ROWID MaTable 3802 334K 1104
    6 INDEX RANGE SCAN IndexTable1 15209 79
    => C'est ce dont on a toujours rêvé !

    Est-ce que quelqu'un sait pourquoi ?
    A vrai dire, je n'ai pas ce problème en général : je stocke l'identifiant du compte dans une variable. Mais il s'agit là d'une vieille requête...

    Ce que j'aimerais, c'est avoir une explication rationnelle du phénomène, ce qui me fournirait des arguments solides pour ensuite convaincre mes amis de faire attention à ce "détail".

    PS : comme on a en ce moment des petits problèmes de perf, on a un peu de mal à savoir ce qui est vraiment du à des requêtes pourries, ou a des problèmes de stats, ou des paramètres systèmes, ...

    Merci !

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 394
    Points
    18 394
    Par défaut
    Citation Envoyé par pacmann Voir le message
    C'est pas très lisible, mais l'important est de voir que le CBO choisit FTS alors que ça aurait été sympa de lire IndexTable1...

    Ce qu'il faut noter, c'est que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (SELECT id_compte FROM TableRef C WHERE nom_compte = 'X')
    Renvoie une seule ligne. (y'a un index unique)
    Notez bien que le FTS a été fait sur la table de référence.

    Vous avez, j'imagine, un index unique sur TableRef.id_compte mais aucun index sur TableRef.nom_compte, qui est la valeur filtrée.

    Essayez un index (pas forcément unique) sur TableRef.nom_compte et remontrez-nous le plan.

  3. #3
    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
    Oops, je me suis planté quand j'ai remplacé les noms de mes tables par leur fausses identités respectives...

    Par ailleurs, il y a bien un index sur la grosse table : les deux côtés de la jointure accèdent à la même table, selon les mêmes critères. Et la première fois, l'accès est bien fait par l'index sur le compte...

    (j'édite le poste initial pour rétablir la vérité)

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 394
    Points
    18 394
    Par défaut
    Autre tentative, je n'y crois pas beaucoup mais essayons :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE a.id_compte = (SELECT C.id_compte FROM TableRef C WHERE C.nom_compte = 'X')
    Que donnerait le plan d'exécution de la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
    FROM MaTable A JOIN MaTable B
      ON a.id_compte = b.id_compte
     AND a.etat = b.etat
        JOIN TableRef c
      ON a.id_compte = c.id_compte
    WHERE c.nom_compte = 'X'
    ORDER BY a.unchamp

  5. #5
    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
    Non plus !

    (J'ai tenté les deux variantes)

    Et en fait, le plus important n'est pas la requête gagnante, puisqu'on l'a déjà...
    (à savoir commencer par récupérer l'identifiant dans une variable, puis passer la variable dans la jointure).
    Le fait est surtout que la différente de comportement me surprend beaucoup...

  6. #6
    Membre expérimenté Avatar de fatsora
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 103
    Points : 1 332
    Points
    1 332
    Par défaut
    quelle est ta version Oracle

    les parameters cursor_sharing , optimizer_mode etc

    voir

    http://www.oracloid.com/2006/07/bind...no-histograms/

  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
    Merci pour ta réponse.

    cursor_sharing : exact
    optimizer_mode : choose.

    Concernant l'article, il parle de bind variable peeking, non ?
    Est-ce que tu peux m'en dire un peu plus sur le lien avec mon problème ?

    Je suppose qu'il pourrait y avoir un problème si l'optimiseur se trompait dans la sélectivité de la sous requête de sélection du compte :
    par rapport à cela, il y a deux points que je voudrais souligner :
    - num_rows / num_distinct = 1 pour cette colonne
    - il y a un unique index sur la colonne...


    EDIT : Ok, je crois que j'ai compris où tu voulais en venir !
    En gros, il se pourrait qu'il prenne le plan d'exécution adéquat pour un autre compte, pour lequel la sélectivité sur la grosse table est faible...
    Cela dit, vu qu'on donne exactement les même filtres pour les deux côtés de la requête (sur la même grosse table), je ne vois pas pourquoi il utiliserait le procédé une seule fois...

    Cela dit, je vais voir si on peut jeter un oeil au 10053...

  8. #8
    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
    Coucou, je reviens à la charge !

    Bon, je suis pas très fort pour décrypter la trace brute... donc j'ai tenté d'autres trucs.

    On a importé / exporté les stats de PROD vers l'environnement de test.
    Et là, tous les accès ce font par index !
    Bon, on a donc cherché ce qui pouvait différer entre la prod et le test dans les paramètres de l'optimiseur... et rien.

    Par contre, on a constaté qu'il y avait un index supplémentaire en prod (oui, je sais...) !

    En résumé :
    Avec 2 index : on full scanne
    Avec 1 index : on lit l'index

    Ca me dépasse... Quelqu'un a une idée ?
    (En atttendant, on va essayer de faire un effort pour se retaper la trace...)

  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
    Petite question bonus :
    Est-ce qu'il y a un outil quelconque pour mettre en forme la 10053 ?
    Ou éventuellement des astuces pour le mettre en forme à la main ?
    (On m'a dit que tkprof ne le fait pas...)

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 750
    Points : 341
    Points
    341
    Par défaut
    je rebondis sur la dernière question de pacman car ça m'interesse.
    Comment lire et interpréter une trace 10053.
    y'a t'il un outil équivalent à Tkprof ?
    Par ailleurs PACMAN as tu trouvé une solution à ton pb ? Avec 2 indexes => FTS avec un seul INDEX => Range Scan

  11. #11
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par farenheiit Voir le message
    je rebondis sur la dernière question de pacman car ça m'interesse.
    Comment lire et interpréter une trace 10053.
    y'a t'il un outil équivalent à Tkprof ?
    Par ailleurs PACMAN as tu trouvé une solution à ton pb ? Avec 2 indexes => FTS avec un seul INDEX => Range Scan
    C'est vieux (Oracle 8i) mais c'est bien expliqué: Wolfgang Breitling, A Look under the Hood of CBO-10053 Event, http://www.centrexcc.com
    Il y a aussi des discutions sur Ask Tom et ailleurs sur l'internet. Mais c'est rarement utile pour des problèmes pratiques.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 750
    Points : 341
    Points
    341
    Par défaut
    J'ai mieux: le chapitre 7 "Event 10053 and the cost based optimizer" du livre de Norbert DEBES "Secrets of the Oracle database"
    http://www.apress.com/book/view/9781430219521
    c'est expliqué plus simplement que dans le livre de Johnathan LEWIS et en plus c'est en 10GR2

  13. #13
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par farenheiit Voir le message
    J'ai mieux: le chapitre 7 "Event 10053 and the cost based optimizer" du livre de Norbert DEBES "Secrets of the Oracle database"
    http://www.apress.com/book/view/9781430219521
    c'est expliqué plus simplement que dans le livre de Johnathan LEWIS et en plus c'est en 10GR2
    Je ne trouve pas le chapitre 7 en téléchargement mais seulement le chapitre 1.

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 750
    Points : 341
    Points
    341
    Par défaut
    Je l'ai trouvé sur sur Emule

Discussions similaires

  1. [2008R2] Question sur un plan d'éxécution
    Par KyoshiroKensei dans le forum MS SQL Server
    Réponses: 11
    Dernier message: 20/08/2014, 12h43
  2. Que signifie le petit symbole sur le plan d'exécution ?
    Par cmako dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 01/09/2009, 15h30
  3. Réponses: 11
    Dernier message: 28/04/2008, 16h29
  4. Réponses: 7
    Dernier message: 11/09/2006, 14h23
  5. Réponses: 12
    Dernier message: 22/06/2006, 10h26

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