Mysterious plan changes

Statistics results may always be different when using sample size. Consider this 
    select * from aldo.persone sample(1)
and run it many times.

Statistics result may obviously change following data changes

col_usage$

2 instances have different plans but exactly same data and updated statistics
Each time you perform a joined query a track is keeped:

SELECT   dba_tab_columns.owner, dba_tab_columns.table_name,
         dba_tab_columns.column_name, SYS.col_usage$.*
    FROM SYS.col_usage$, dba_objects, dba_tab_columns
   WHERE obj# = dba_objects.object_id
     AND dba_tab_columns.owner = dba_objects.owner
     AND dba_tab_columns.table_name = dba_objects.object_name
     AND intcol# = dba_tab_columns.column_id
     AND dba_objects.owner = 'ALDO'
     AND object_name = 'T'
ORDER BY intcol#

See how histograms statistics are taken:

SELECT *
  FROM dba_tab_histograms
 WHERE owner = 'ALDO' AND table_name = 'T' AND column_name = 'ID'

 

Demonstration
This apply to method_opt=>'FOR ALL COLUMNS SIZE AUTO' when taking stats (default value in 10g)
    
create table t as
select mod(rownum, 5) id, a.*
from dba_objects a

Each time you perform a joined query a track is keeped:

SELECT   dba_tab_columns.owner, dba_tab_columns.table_name,
         dba_tab_columns.column_name, SYS.col_usage$.*
    FROM SYS.col_usage$, dba_objects, dba_tab_columns
   WHERE obj# = dba_objects.object_id
     AND dba_tab_columns.owner = dba_objects.owner
     AND dba_tab_columns.table_name = dba_objects.object_name
     AND intcol# = dba_tab_columns.column_id
     AND dba_objects.owner = 'ALDO'
     AND object_name = 'T'
ORDER BY intcol#

** No data returned *** a joined query has never been performed or 
SYS.col_usage$ has not been updated

See how histograms statistics are taken:

SELECT *
  FROM dba_tab_histograms
 WHERE owner = 'ALDO' AND table_name = 'T' AND column_name = 'ID'
 
** No data returned *** Statistics has probably never been taken

begin
dbms_stats.gather_table_stats(user, 'T', method_opt=>'FOR ALL COLUMNS SIZE AUTO');
end;

See how histograms statistics are taken:

SELECT *
  FROM dba_tab_histograms
 WHERE owner = 'ALDO' AND table_name = 'T' AND column_name = 'ID'

OWNER   TABLE_NAME  COLUMN_NAME ENDPOINT_NUMBER ENDPOINT_VALUE ENDPOINT_ACTUAL_VALUE
ALDO    T           ID          0               0	          
ALDO    T           ID          1               4	

select * from t where id = 1

begin
dbms_stats.gather_table_stats(user, 'T', method_opt=>'FOR ALL COLUMNS SIZE AUTO');
end;

Now we see the track of the joined query

SELECT   dba_tab_columns.owner, dba_tab_columns.table_name,
         dba_tab_columns.column_name, SYS.col_usage$.*
    FROM SYS.col_usage$, dba_objects, dba_tab_columns
   WHERE obj# = dba_objects.object_id
     AND dba_tab_columns.owner = dba_objects.owner
     AND dba_tab_columns.table_name = dba_objects.object_name
     AND intcol# = dba_tab_columns.column_id
     AND dba_objects.owner = 'ALDO'
     AND object_name = 'T'
ORDER BY intcol#

OWNER TABLE_NAME COLUMN_NAME OBJ# INTCOL# EQUALITY_PREDS EQUIJOIN_PREDS NONEQUIJOIN_PREDS RANGE_PREDS LIKE_PREDS NULL_PREDS TIMESTAMP
ALDO T ID 62895 1 1 0 0 0 0 0 22/05/2006 11.44.52
select * from dba_tab_histograms where owner ='ALDO' and table_name = 'T' and column_name = 'ID'
OWNER TABLE_NAME COLUMN_NAME ENDPOINT_NUMBER ENDPOINT_VALUE ENDPOINT_ACTUAL_VALUE
ALDO T ID 943 0  
ALDO T ID 1927 1  
ALDO T ID 2928 2  
ALDO T ID 3934 3  
ALDO T ID 4942 4  
As you can see when the stats are taken a different method is applied based, in the second case more istograms are taken