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

Oracle Discussion :

Index BITMAP non utilisé


Sujet :

Oracle

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 45
    Points : 18
    Points
    18
    Par défaut Index BITMAP non utilisé
    Bonjour,
    j'ai une table de 75 million de lignes avec une colonne CODE_STE varchar2(2) qui peut avoir cinq valeurs distinctes, donc c'est le cas idéal pour créer un index BITMAP.
    je créé l'index je lance ma requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select col1, col2, ......
    from MA_TABLE
    where CODE_STE ='07';
    Résultat : la requête dure une éternité car oracle fait un full scan de MA_TABLE !!!!!

    Pouriez_vous me dire pourquoi Oracle ne passe pas par mon INDEX ?

    parcontre quand je fais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select count(*) from MA_TABLE  where CODE_STE ='07';
    Oracle passe par l'index .

  2. #2
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    Oracle ne prends pas ton index parceque de toutes façon il devra remonter tous les blocs de la table (Oracle ne travaille pas à la ligne mais au bloc pour ses lectures) donc il n'a aucun intérêt à lire l'index.

  3. #3
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 45
    Points : 18
    Points
    18
    Par défaut
    Normalement on passant par l'index il remontera que les blocs où se trouve les lignes CODE_STE='07' ? c'est le but des index .

  4. #4
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    Certes mais un bloc contient généralement plusieurs lignes.

    Mettons que chaque bloc contienne 20 lignes. Tu dis n'avoir que 5 valeurs pour pour CODE_STE. Si ces valeurs sont uniformament réparties dans ta table il y a environ 4 lignes par blocs qui réponde à ta demande, donc tous les blocs doivent être remontés.

  5. #5
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Points : 4 926
    Points
    4 926
    Par défaut
    Citation Envoyé par olap_2001 Voir le message
    Bonjour,
    j'ai une table de 75 million de lignes avec une colonne CODE_STE varchar2(2) qui peut avoir 5 valeurs distinctes, donc c'est le cas idéal pour créer un index BITMAP.
    C'est faux de croire ça.

    Si tu as 5 valeurs distinctes et que tu sélectionnes 20% de la table, il y a de fortes chance que le full table scan soit plus rapide.

    Si tu avais 75 Millions de lignes et un bitmap sur 100'000 valeurs distintes, alors là oui, ce serait le cas idéal.

    Le seul cas où un bitmap de cardinalité 1/15000000 peut se révéler utile, c'est lorsqu'il est employé avec d'autres bitmaps.

    Dans le cas du count(*), c'est très différent car il ne doit pas accèder à la table du tout.

  6. #6
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 45
    Points : 18
    Points
    18
    Par défaut
    Non les valeurs de cod_ste ne sont pas uniformément réparties.
    COD_STE a 5 valeurs distincts .

    La table contient 70 millions de lignes mais uniquement 23000 lignes correspondes à COD_STE='07' et à ma connaissance c'est dans ce cas ou il faut utiliser un index BITMAP.

    les lignes de COD_STE='07' c'est des lignes d'une nouvelle société quant vient de rajouter dans la base.

  7. #7
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    Dans ce cas, il faut calculer des statistiques avec histogrammes sur la colonne CODE_STE, en effet sans histogramme, l'optimiseur Oracle se comporte comme si les données étaient uniformément réparties.

  8. #8
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Points : 4 926
    Points
    4 926
    Par défaut
    dans ce cas effectivement un index scan serait moins cher.

    Quel est l'output de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    set autot trace exp
    select /*+FULL(MA_TABLE)*/ col1,col2 from MA_TABLE where CODE_STE='07';
    select /*+INDEX(MA_TABLE)*/ col1,col2 from MA_TABLE where CODE_STE='07';

  9. #9
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 45
    Points : 18
    Points
    18
    Par défaut
    Voici les plans d’exécution.
    Dans le premier cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    -- Plan d'exécution
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=417034 Card=10319404
               Bytes=2136116628)
     
       1    0   TABLE ACCESS (FULL) OF 'MA8TABLE' (Cost=417034 Card=10319
              404 Bytes=2136116628)
    Dans le second cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    -- Plan d'exécution
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1815072 Card=1031940
              4 Bytes=2136116628)
     
       1    0   TABLE ACCESS (BY INDEX ROWID) OF 'MA_TABLE' (Cost=1815072
               Card=10319404 Bytes=2136116628)
     
       2    1     INDEX (FULL SCAN) OF 'IXB1_EDBFI_EVT' (NON-UNIQUE) (Cost
              =248435 Card=72239610)
    Sachant que l'index IXB1_EDBFI_EVT n'a rien avoir avec la colonne CODE_STE.

  10. #10
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Points : 4 926
    Points
    4 926
    Par défaut
    et puis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT /*+INDEX(MA_TABLE bmi)*/ col1,col2 FROM MA_TABLE WHERE CODE_STE='07';
    ?

    où BMI est le nom de ton index

  11. #11
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 45
    Points : 18
    Points
    18
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    -- Plan d'exécution
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1552170 Card=1031940
              4 Bytes=2136116628)
     
       1    0   TABLE ACCESS (BY INDEX ROWID) OF 'MA_TABLE' (Cost=1552170
               Card=10319404 Bytes=2136116628)
     
       2    1     BITMAP CONVERSION (TO ROWIDS)
       3    2       BITMAP INDEX (SINGLE VALUE) OF 'IX6_EVT_CD_STE'

  12. #12
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    2 1 INDEX (FULL SCAN) OF 'IXB1_EDBFI_EVT' (NON-UNIQUE) (Cost=248435 Card=72239610)

    L'index inqique une cardinalité très supérieure au nombre de lignes de la table. A priori la table a été mise à jour sur cette colonne et l'index n'est plus efficace même pour une valeur discrète.

    Si peu de mises à jours sont effectuées sur la table, il faut reconstruire les index bitmaps après celles-ci.

    Si beaucoup de mises à jour ont lieu sur la table il ne faut, en théorie, pas utiliser d'index bitmap.

  13. #13
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 45
    Points : 18
    Points
    18
    Par défaut
    quelle est la commande à lancer pour calculer des statistiques avec histogrammes sur la colonne CODE_STE

  14. #14
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    Cette commande doit le faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    exec dbms_stats.gather_table_stats(USER,'MA_TABLE',null,null,null,'FOR COLUMNS CODE_STE SIZE 254')

  15. #15
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 45
    Points : 18
    Points
    18
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    begin
    dbms_stats.gather_table_stats(ownname =>'AAA', tabname =>'MA_TABLE',
      3   estimate_percent => 50, cascade => TRUE,
      4   method_opt =>'FOR COLUMNS CODE_STE SIZE 254');
      5* end;
    SQL> /
    begin
    *
    ERREUR à la ligne 1 :
    ORA-06521: PL/SQL: Error mapping function
    ORA-06512: at "SYS.DBMS_STATS", line 10301
    ORA-06512: at "SYS.DBMS_STATS", line 10315
    ORA-06512: at line 2
    As-tu une idée ?

  16. #16
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    il y a un soucis avec le dictionnaire de données

    Lire la note MOS n°1149109.1

  17. #17
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 45
    Points : 18
    Points
    18
    Par défaut
    comme le DBMS_STATS n’est pas installé comment je peux executer l'equivalent du code ci-dessous ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    exec dbms_stats.gather_table_stats(user,                            
                   'DEMO', method_opt=>'FOR COLUMNS COL1 SIZE SKEWONLY', 
                   cascade=> true)
    Merci par avance

  18. #18
    Expert éminent
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    Novembre 2007
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

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

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 821
    Points : 6 443
    Points
    6 443
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    La table contient 70 millions de lignes mais uniquement 23000 lignes correspondes à COD_STE='07' et à ma connaissance c'est dans ce cas ou il faut utiliser un index BITMAP.
    Si c'est très selectif, alors un index est intéressant. Dans ce cas avec histogramme, à jour, et en étant sûr de ne pas être en cursor_sharing=force

    Mais pas forçément un index bitmap.

    Vu comme ça, ça me paraît un cas idéal de partitionnement...

    Cordialement,
    Franck.
    Franck Pachot - Developer Advocate Yugabyte 🚀 Base de Données distribuée, open source, compatible PostgreSQL
    🗣 twitter: @FranckPachot - 📝 blog: blog.pachot.net - 🎧 podcast en français : https://anchor.fm/franckpachot

  19. #19
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 45
    Points : 18
    Points
    18
    Par défaut
    Mais pas forcément un index bitmap ? il ya très peu de valeur distinctes donc un bitmap est conseillé.

    citation :
    Vu comme ça, ça me paraît un cas idéal de partitionnement...

    justement le DBA nous a suggéré de faire des vues matérialisées sachant que le requête des MV c'est :
    select * from MA_TABLE where CD_STE=A; ou A in ('01','02','03' ....'07')

    moi j'était pour le partitionnement de la table mais d'après le dba c'est mieux de faire des MV !!!!

  20. #20
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Points : 4 926
    Points
    4 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    il ya très peu de valeur distinctes donc un bitmap est conseillé.
    archi-faux.

    Un bitmap a de très nombreux inconvénients, et ne convient qu'aux environments style datawarehouse où ils n'y a pas deux utilisateurs qui entrent des données simultanément

    Autant les tables que les vues matérialisées peuvent être partitionées, change de dba

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

Discussions similaires

  1. Index fullText non utilisé (Version 2)
    Par moumoune65 dans le forum Requêtes
    Réponses: 2
    Dernier message: 21/10/2011, 08h01
  2. Index non utilisé dans une requête
    Par tibal dans le forum Administration
    Réponses: 9
    Dernier message: 10/05/2010, 15h29
  3. [Oracle 11g] Index non utilisé par oracle
    Par eryk71 dans le forum SQL
    Réponses: 12
    Dernier message: 17/02/2009, 10h29
  4. index non utilisé
    Par puck78 dans le forum SQL
    Réponses: 10
    Dernier message: 21/01/2009, 14h36
  5. Oracle8i Index Bitmap non utilisé
    Par persam dans le forum SQL
    Réponses: 2
    Dernier message: 20/06/2008, 15h05

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