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 :
Dans ma table j'ai une PK qui inclus la date, un index sur {date, magasin} et un autre sur la date uniquement.
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) );
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 #3Pour ê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 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
Merci d'avance de votre aide.
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 - ) /
Partager