Retour arrière sur vos statistiques

Oracle 11g historise les statistiques de votre base de données. Cela permet de revenir en arrière. Vous conviendrez que ce type de manipulation est parfois une fausse bonne idée dans la mesure où, si les statistiques ont été collectées, c’est, espérons, parce que leur ancienne version ne représentaient plus vraiment les données. Revenir en arrière, ne vous sauvera donc pas toujours. Je ne lancerai pas un débat sur la manière de collecter les statistiques. Toutefois, partageons, ci-dessous, quelques commandes pour manipuler l’historique des statistiques

Période de rétention des statistiques

Le package dbms_stats et les vues du dictionnaire de données constituent les outils pour manipuler l’historique des statistiques. Par exemple, ci-dessous, vous pouvez visualiser la rétention des statistiques définie dans votre base de données :

select dbms_stats.get_stats_history_retention
from dual;

GET_STATS_HISTORY_RETENTION
---------------------------
31

Un exemple simple

Dans ce qui suit, vous trouverez un exemple simple dont j’ai déjà parlé; il s’agit d’observer que les histogrammes sont collectés automatiquement sur les colonnes qui sont utilisées dans les clauses WHERE des select. Pour cela, nous allons créer une table avec des données, non uniformément distribuées:

sqlplus scott/tiger

create table X(
id number,
text varchar2(1000));

create index X_idx on X(id);

insert into X
(select rownum+1,
rpad('X',900,'Y')
from dual
connect by level <= 10000);


insert into X
(select 1,
rpad('X',900,'Y')
from dual
connect by level <= 10000);

commit;

exec dbms_stats.gather_table_stats( -
user, -
'X', -
method_opt=>'FOR ALL COLUMNS SIZE AUTO');

col column_name format a5
select column_name,
count(*)
from user_histograms
where table_name='X'
group by column_name

COLUM COUNT(*)
----- ----------
TEXT 2
ID 2

Comme vous pouvez l’apercevoir, par défaut et malgré la stratégie automatique, aucun histogramme n’est collecté; exécutons une requête qui inclus la colonne ID dans sa clause WHERE et reprenons les statistiques; les histogrammes sont collectés:

var x number
exec :x:=2;

select text
from x
where id=:x;

exec dbms_stats.gather_table_stats( -
user, -
'X', -
method_opt=>'FOR ALL COLUMNS SIZE AUTO');

col column_name format a5
select column_name,
count(*)
from user_histograms
where table_name='X'
group by column_name

COLUM COUNT(*)
----- ----------
TEXT 2
ID 129

Statistiques: retour arrière

Pour revenir en arrière, on peut vérifier les différentes versions des statistiques dans user_tab_stats_history comme ci-dessous:

alter session set nls_date_format='DD/MM/YYYY HH24:MI:SS';
select last_analyzed
from user_tables
where table_name='X';

LAST_ANALYZED
-------------------
07/03/2010 14:31:33


select STATS_UPDATE_TIME
from user_tab_stats_history
where table_name='X' order by 1;

STATS_UPDATE_TIME
-----------------------------------
07-MAR-10 02.27.44.376474 PM +01:00
07-MAR-10 02.29.59.569304 PM +01:00
07-MAR-10 02.31.33.503626 PM +01:00

Restaurer consiste alors à utiliser dbms_stats.restore_table_stats comme ci-dessous :

exec dbms_stats.restore_table_stats( -
user, 'X', -
to_timestamp_tz('07-MAR-10 02.30.00.00000 PM +01:00',-
'DD-MON-YY HH.MI.SSxFF AM TZH:TZM'))

select column_name, count(*)
from user_histograms
where table_name='X'
group by column_name;

COLUM COUNT(*)
----- ----------
TEXT 2
ID 2


select STATS_UPDATE_TIME
from user_tab_stats_history
where table_name='X'
order by 1;

STATS_UPDATE_TIME
-----------------------------------
07-MAR-10 02.27.44.376474 PM +01:00
07-MAR-10 02.29.59.569304 PM +01:00
07-MAR-10 02.31.33.503626 PM +01:00
07-MAR-10 03.05.02.101079 PM +01:00

Vous remarquerez que l’historique des versions de statistiques n’est pas supprimé; au contraire, une nouvelle version des statistiques est créée.

Fin…

Vous finirez par une note optimiste :

drop table X purge;