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 :

Problème avec le CBO d'Oracle sur filtre simple


Sujet :

SQL Oracle

  1. #1
    Scorpi0
    Invité(e)
    Par défaut Problème avec le CBO d'Oracle sur filtre simple
    Bonjour,

    Suite à une requête basique de type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Select t1.col1, t1.col2,...
    from table1 t1 inner join table2 t2
                   left outer join table3 t3
    etc..
    where [filtre divers]
    and t1.col3 = 'toto'
    La table t1 contient environ 1.3 million de lignes.
    La col3 contient exactement 18 valeurs distinctes, et 1.2 million de lignes correspondent à col3 = 'toto'. Autant dire que la requête devrait taper un full scan sur table1.

    Le problème est qu'avec le filtre "and t1.col3 = 'toto'", l'explain plan explose avec l'utilisation d'index non pertinent, et la requete ne répond plu.
    Si j'enleve ce filtre, l'explain plan fait son boulot en me full scannant ce qu'il faut et en hash outer joignant comme il faut, et me repond en 10 minutes.

    Je suis allé faire un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Select density
    from user_tab_col_statistics
    where table_name = 'TABLE1'
    and column_name = 'COL3'
    Et j'ai donc 0.05555 = 1/18 (CF http://marius-nitu.developpez.com/tu...-calcule-cout/). J'ai peur que le CBO réagit comme si ma col3 etait parfaitement distribué, ce qui est tres tres loin d'etre le cas.
    Pour linstant je contourne le probleme avec un hint pour fullscanner ma table1, mais j'aimerais bien savoir comment dire à oracle de faire les stats sur cette colonne en un peu plus intelligent !!

    J'ai aussi tenter de créer un index sur COL3, pour 'ouvrir' les yeux au CBO, mais ca n'a pas mieux fonctionner, il s'entete a croire que la clause "t1.col3 = 'toto'" va lui ramener quelques lignes alors que ca va lui ramener la table entiere !

    NB : ma commande pour passer les stats
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     DBMS_STATS.gather_table_stats(ownname => 'SYS' , 
      tabname => 'TABLE1',
      cascade => true, estimate_percent => 100,granularity => 'ALL', degree => 1);
    NB2 : Mon Oracle : Oracle9i Release 9.2.0.4.0
    Dernière modification par Scorpi0 ; 22/06/2009 à 17h36.

  2. #2
    Expert confirmé 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
    Par défaut
    Si les 18 valeurs sont distribués d'une manière non-uniforme vous devez collecter des histogrammes sur cette colonne pour informer l'optimiseur de cette distribution. Ensuite il fera de meilleurs estimations.
    Mais dans ce cas il sera bien que le filtre utilise la valeur littérale et non pas une variable de liaison.

  3. #3
    Expert confirmé
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    Novembre 2007
    Messages
    1 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 822
    Billets dans le blog
    1
    Par défaut
    Bonjour,
    Tu peux rajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    method_opt=>'FOR COLUMNS COL3'
    au dbms_stats, ou toute autre variation
    Cordialement,
    Franck.

  4. #4
    Scorpi0
    Invité(e)
    Par défaut
    Merci !

    C'était bien l'option method_opt qui me manquait !
    Donc la cardinalité retourné par ma requete sur la table de base était de beaucoup inférieure à la réalité, ce qui provoquait un cout ammoindri et un plan d'éxecution mauvais.

    J'ai trouvé une très bonne explication ici :

    http://structureddata.org/2008/10/14...dexed-columns/

    Au final, l'option j'ai du précisé mon nombre de tranche (bucket) de mon histogramme car l'option skewonly ne me rendait pas une bonne modélisation.

    La commande finale qui a marché :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      DBMS_STATS.gather_table_stats
      (
        ownname => 'SYS', 
        tabname => 'TABLE1',
        estimate_percent => 100,
       method_opt=>'FOR COLUMNS COL3 size 20'
      );

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/10/2006, 18h05
  2. Réponses: 8
    Dernier message: 11/10/2006, 17h28
  3. Problème avec Socket et/ou Telnet sur le manager d'Asterisk
    Par gorby69 dans le forum Programmation et administration système
    Réponses: 1
    Dernier message: 21/07/2006, 14h47
  4. [AJAX] Ajax en mode synchrone sur Safari
    Par The Blec dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 17/02/2006, 17h52
  5. [tomcat] [jsp] Problème avec driver OCI pour oracle
    Par nanardcompanie dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 01/07/2004, 09h54

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