Précédent   Forum des professionnels en informatique > Bases de données > Oracle
Oracle Forum Oracle : le serveur, les outils, ... Voir F.A.Q Oracle Tutoriels Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/03/2011, 09h36   #1
Invité de passage
 
Inscription : janvier 2011
Messages : 44
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 44
Points : 2
Points : 2
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 :
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 :
SELECT count(*) FROM MA_TABLE  WHERE CODE_STE ='07';
Oracle passe par l'index .
olap_2001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 09h54   #2
Membre chevronné
 
Homme O. Joly
Support
Inscription : décembre 2010
Messages : 287
Détails du profil
Informations personnelles :
Nom : Homme O. Joly
Âge : 38
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : Support
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : décembre 2010
Messages : 287
Points : 617
Points : 617
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.
ojo77 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 30/03/2011, 10h02   #3
Invité de passage
 
Inscription : janvier 2011
Messages : 44
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 44
Points : 2
Points : 2
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 .
olap_2001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 10h20   #4
Membre chevronné
 
Homme O. Joly
Support
Inscription : décembre 2010
Messages : 287
Détails du profil
Informations personnelles :
Nom : Homme O. Joly
Âge : 38
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : Support
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : décembre 2010
Messages : 287
Points : 617
Points : 617
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.
ojo77 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 30/03/2011, 10h34   #5
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 925
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

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

Informations forums :
Inscription : décembre 2005
Messages : 2 925
Points : 4 547
Points : 4 547
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.
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 30/03/2011, 10h39   #6
Invité de passage
 
Inscription : janvier 2011
Messages : 44
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 44
Points : 2
Points : 2
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.
olap_2001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 10h41   #7
Membre chevronné
 
Homme O. Joly
Support
Inscription : décembre 2010
Messages : 287
Détails du profil
Informations personnelles :
Nom : Homme O. Joly
Âge : 38
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : Support
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : décembre 2010
Messages : 287
Points : 617
Points : 617
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.
ojo77 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 30/03/2011, 10h44   #8
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 925
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

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

Informations forums :
Inscription : décembre 2005
Messages : 2 925
Points : 4 547
Points : 4 547
dans ce cas effectivement un index scan serait moins cher.

Quel est l'output de

Code :
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';
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 30/03/2011, 11h03   #9
Invité de passage
 
Inscription : janvier 2011
Messages : 44
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 44
Points : 2
Points : 2
Voici les plans d’exécution.
Dans le premier cas :
Code :
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 :
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.
olap_2001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 11h06   #10
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 925
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

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

Informations forums :
Inscription : décembre 2005
Messages : 2 925
Points : 4 547
Points : 4 547
et puis

Code :
SELECT /*+INDEX(MA_TABLE bmi)*/ col1,col2 FROM MA_TABLE WHERE CODE_STE='07';
?

où BMI est le nom de ton index
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 11h26   #11
Invité de passage
 
Inscription : janvier 2011
Messages : 44
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 44
Points : 2
Points : 2
Code :
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'
olap_2001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 11h39   #12
Membre chevronné
 
Homme O. Joly
Support
Inscription : décembre 2010
Messages : 287
Détails du profil
Informations personnelles :
Nom : Homme O. Joly
Âge : 38
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : Support
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : décembre 2010
Messages : 287
Points : 617
Points : 617
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.
ojo77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 12h04   #13
Invité de passage
 
Inscription : janvier 2011
Messages : 44
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 44
Points : 2
Points : 2
quelle est la commande à lancer pour calculer des statistiques avec histogrammes sur la colonne CODE_STE
olap_2001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 12h21   #14
Membre chevronné
 
Homme O. Joly
Support
Inscription : décembre 2010
Messages : 287
Détails du profil
Informations personnelles :
Nom : Homme O. Joly
Âge : 38
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : Support
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : décembre 2010
Messages : 287
Points : 617
Points : 617
Cette commande doit le faire
Code :
exec dbms_stats.gather_table_stats(USER,'MA_TABLE',NULL,NULL,NULL,'FOR COLUMNS CODE_STE SIZE 254')
ojo77 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 30/03/2011, 14h36   #15
Invité de passage
 
Inscription : janvier 2011
Messages : 44
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 44
Points : 2
Points : 2
Code :
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 ?
olap_2001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 17h28   #16
Membre chevronné
 
Homme O. Joly
Support
Inscription : décembre 2010
Messages : 287
Détails du profil
Informations personnelles :
Nom : Homme O. Joly
Âge : 38
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : Support
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : décembre 2010
Messages : 287
Points : 617
Points : 617
il y a un soucis avec le dictionnaire de données

Lire la note MOS n°1149109.1
ojo77 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 31/03/2011, 16h29   #17
Invité de passage
 
Inscription : janvier 2011
Messages : 44
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 44
Points : 2
Points : 2
comme le DBMS_STATS n’est pas installé comment je peux executer l'equivalent du code ci-dessous ?

Code :
1
2
3
exec dbms_stats.gather_table_stats(user,                            
               'DEMO', method_opt=>'FOR COLUMNS COL1 SIZE SKEWONLY', 
               cascade=> true)
Merci par avance
olap_2001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/03/2011, 23h54   #18
Membre Expert
 
Avatar de pachot
 
Homme Franck Pachot
DBA Oracle
Inscription : novembre 2007
Messages : 703
Détails du profil
Informations personnelles :
Nom : Homme Franck Pachot
Âge : 41
Localisation : Suisse

Informations professionnelles :
Activité : DBA Oracle
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2007
Messages : 703
Points : 1 630
Points : 1 630
Bonjour,

Citation:
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.
__________________
A lire sur mon blog Oracle - Articles d'Experts des articles traduits en français de Jonathan Lewis, Tom Kyte, Doug Burns, Cary Millsap, Greg Rahn ...
pachot est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 01/04/2011, 13h31   #19
Invité de passage
 
Inscription : janvier 2011
Messages : 44
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 44
Points : 2
Points : 2
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 !!!!
olap_2001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/04/2011, 13h40   #20
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 925
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

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

Informations forums :
Inscription : décembre 2005
Messages : 2 925
Points : 4 547
Points : 4 547
Code :
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
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h57.


 
 
 
 
Partenaires

Hébergement Web