Bonjour,


Dans mon datawarehouse (Oracle 10g), j'ai une table de 8 millions (4Go) d'enregistrements. Pour optimiser les requêtes j'ai décidé de partitionner ma table sur une colonne date comme suit :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
PARTITION BY RANGE(DATE) 
(
PARTITION PART1 values less than (TO_DATE('01/01/2009','DD/MM/YYYY')), 
PARTITION PART2 values less than (TO_DATE('01/01/2010','DD/MM/YYYY')),  
PARTITION PART3 values less than (TO_DATE('01/01/2011','DD/MM/YYYY')), 
PARTITION PART4 values less than (TO_DATE('01/01/2012','DD/MM/YYYY')),
PARTITION PART5 values less than (TO_DATE('01/01/2013','DD/MM/YYYY')),  
PARTITION PART6 values less than (MAXVALUE)
);
Dans ma table j'ai une PK qui inclus la date, un index sur {date, magasin} et un autre sur la date uniquement.
Ces index sont locaux.
Ce qui m'étonne c'est que les performances sur la table partitionnée sont moins bonnes que sur la table non partitionnée.

En effet, la requête ci dessous met 1 minute sur la table partionnée vs 10 secondes sur la table normale.
Ci-dessous les requêtes ainsi que les plans d'exécution :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
select date,sum(indicator) from PARTITIONNED_TABLE 
where date between '01/01/2010' and '31/01/2010'
group by date
 
 
Plan
SELECT STATEMENT  FIRST_ROWSCost: 11  Bytes: 100  Cardinality: 10  CPU Cost: 61,864  IO Cost: 11  Time: 1  				
	4 PARTITION RANGE SINGLE  Cost: 11  Bytes: 100  Cardinality: 10  CPU Cost: 61,864  IO Cost: 11  Time: 1  Partition #: 1  Partitions accessed #3			
		3 SORT GROUP BY NOSORT  Cost: 11  Bytes: 100  Cardinality: 10  CPU Cost: 61,864  IO Cost: 11  Time: 1  		
			2 TABLE ACCESS BY LOCAL INDEX ROWID TABLE DWH.PARTITIONNED_TABLE  Cost: 11  Bytes: 100  Cardinality: 10  CPU Cost: 61,864  IO Cost: 11  Time: 1  Partition #: 3  Partitions accessed #3	
				1 INDEX RANGE SCAN INDEX DWH.INDEX_DATE Cost: 3  CPU Cost: 23,364  IO Cost: 3  Time: 1  Partition #: 4  Partitions accessed #3
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
select date,sum(indicator) from NON_PARTITIONNED_TABLE 
where date between '01/01/2010' and '31/01/2010'
group by date
 
Plan
SELECT STATEMENT  FIRST_ROWSCost: 10  Bytes: 108  Cardinality: 12  CPU Cost: 76,614  IO Cost: 10  Time: 1  			
	3 SORT GROUP BY NOSORT  Cost: 10  Bytes: 108  Cardinality: 12  CPU Cost: 76,614  IO Cost: 10  Time: 1  		
		2 TABLE ACCESS BY INDEX ROWID TABLE DWH.NON_PARTITIONNED_TABLE Cost: 10  Bytes: 2,030,544  Cardinality: 225,616  CPU Cost: 76,614  IO Cost: 10  Time: 1  	
			1 INDEX RANGE SCAN INDEX DWH.INDEX_DATE Cost: 3  Cardinality: 12  CPU Cost: 23,764  IO Cost: 3  Time: 1
Pour être complet j'ai lancé un calcul de statistiques sur la table avec le script suivant :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
exec dbms_stats.gather_table_stats ( -
     ownname          => 'DWH', -
     tabname          => 'PARTITIONNED_TABLE', -
     estimate_percent => dbms_stats.auto_sample_size, -
     method_opt       => 'FOR ALL INDEXED COLUMNS SIZE SKEWONLY', -
     cascade          => true, -
     granularity => 'ALL' , -
     degree           => 5 -
)
/
Merci d'avance de votre aide.