查看统计信息是否过期

SQL> drop table test purge;

Table dropped.

SQL> create table test as select * from dba_objects;

Table created.

SQL> select owner, table_name name, object_type, stale_stats, last_analyzed
  from dba_tab_statistics
 where table_name in ('TEST')
   and owner = 'TEST'
   and (stale_stats = 'YES' or last_analyzed is null);  2    3    4    5  

OWNER			       NAME			      OBJECT_TYPE  STA LAST_ANAL
------------------------------ ------------------------------ ------------ --- ---------
TEST			       TEST			      TABLE

开始搜集统计信息:

SQL> select owner, table_name name, object_type, stale_stats, last_analyzed
  from dba_tab_statistics
 where table_name in ('TEST')
   and owner = 'TEST'
   and (stale_stats = 'YES' or last_analyzed is null);  2    3    4    5  

OWNER			       NAME			      OBJECT_TYPE  STA LAST_ANAL
------------------------------ ------------------------------ ------------ --- ---------
TEST			       TEST			      TABLE

SQL> BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'TEST',
                                tabname          => 'TEST',
                                estimate_percent => 100,
                                method_opt       => 'for all columns size repeat',
                                no_invalidate    => FALSE,
                                degree           => 8,
                                cascade          => TRUE);
END;
  2    3    4    5    6    7    8    9   10  /

PL/SQL procedure successfully completed.

SQL> select owner, table_name name, object_type, stale_stats, last_analyzed
  from dba_tab_statistics
 where table_name in ('TEST')
   and owner = 'TEST'
   and (stale_stats = 'YES' or last_analyzed is null);  2    3    4    5  

no rows selected


删除10%的数据:
SQL> select count(*) from test;

  COUNT(*)
----------
     72530

SQL> delete from test where rownum<=72530*0.1;

7253 rows deleted.

SQL> commit;

Commit complete.

SQL> select owner, table_name name, object_type, stale_stats, last_analyzed
  from dba_tab_statistics
 where table_name in ('TEST')
   and owner = 'TEST'
   and (stale_stats = 'YES' or last_analyzed is null);  2    3    4    5  

no rows selected

SQL> exec dbms_stats.flush_database_monitoring_info; ---数据输入磁盘

PL/SQL procedure successfully completed.

SQL> select owner, table_name name, object_type, stale_stats, last_analyzed
  from dba_tab_statistics
 where table_name in ('TEST')
   and owner = 'TEST'
   and (stale_stats = 'YES' or last_analyzed is null);  2    3    4    5  

no rows selected

SQL> delete from test where rownum<=72530*0.3;

21759 rows deleted.

SQL> commit;

Commit complete.

SQL> select owner, table_name name, object_type, stale_stats, last_analyzed
  from dba_tab_statistics
 where table_name in ('TEST')
   and owner = 'TEST'
   and (stale_stats = 'YES' or last_analyzed is null);  2    3    4    5  

no rows selected

SQL> exec dbms_stats.flush_database_monitoring_info;

PL/SQL procedure successfully completed.

SQL> select owner, table_name name, object_type, stale_stats, last_analyzed
  from dba_tab_statistics
 where table_name in ('TEST')
   and owner = 'TEST'
   and (stale_stats = 'YES' or last_analyzed is null);  2    3    4    5  

OWNER			       NAME			      OBJECT_TYPE  STA LAST_ANAL
------------------------------ ------------------------------ ------------ --- ---------
TEST			       TEST			      TABLE	   YES 15-JAN-01

怎么样才算统计信息过期,是不是 表中有 10% 的数据变化了。



---查看表的采样率:
SELECT owner,
       table_name,
       num_rows,
       sample_size,
       trunc(sample_size / num_rows * 100) estimate_percent 
  FROM DBA_TAB_STATISTICS
 WHERE owner='SCOTT' AND table_name='TEST';


有时候收集统计信息不会设置这个参数,method_opt

---------------------------------------------------------
SQL> create table test as select * from dba_objects;

Table created.

SQL> EXEC DBMS_STATS.gather_table_stats('TEST','TEST');

PL/SQL procedure successfully completed.

SQL>  select a.column_name,
       b.num_rows,
       a.num_distinct Cardinality,
        round(a.num_distinct / b.num_rows * 100, 2) selectivity,
       a.histogram,
       a.num_buckets
  from dba_tab_col_statistics a, dba_tables b
 where a.owner = b.owner
   and a.table_name = b.table_name
   and a.owner = 'TEST'
   and a.table_name = 'TEST';
  2    3    4    5    6    7    8    9   10   11  
COLUMN_NAME			 NUM_ROWS CARDINALITY SELECTIVITY HISTOGRAM	  NUM_BUCKETS
------------------------------ ---------- ----------- ----------- --------------- -----------
OWNER				    72530	   30	      .04 NONE			    1
OBJECT_NAME			    72530	43728	    60.29 NONE			    1
SUBOBJECT_NAME			    72530	  114	      .16 NONE			    1
OBJECT_ID			    72530	72530	      100 NONE			    1
DATA_OBJECT_ID			    72530	 7687	     10.6 NONE			    1
OBJECT_TYPE			    72530	   44	      .06 NONE			    1
CREATED 			    72530	 1093	     1.51 NONE			    1
LAST_DDL_TIME			    72530	 1143	     1.58 NONE			    1
TIMESTAMP			    72530	 1214	     1.67 NONE			    1
STATUS				    72530	    2		0 NONE			    1
TEMPORARY			    72530	    2		0 NONE			    1

COLUMN_NAME			 NUM_ROWS CARDINALITY SELECTIVITY HISTOGRAM	  NUM_BUCKETS
------------------------------ ---------- ----------- ----------- --------------- -----------
GENERATED			    72530	    2		0 NONE			    1
SECONDARY			    72530	    2		0 NONE			    1
NAMESPACE			    72530	   21	      .03 NONE			    1
EDITION_NAME			    72530	    0		0 NONE			    0

15 rows selected.

SQL> SELECT owner,
       table_name,
       num_rows,
       sample_size,
       trunc(sample_size / num_rows * 100) estimate_percent 
  FROM DBA_TAB_STATISTICS
 WHERE owner='SCOTT' AND table_name='TEST';  2    3    4    5    6    7  

OWNER			       TABLE_NAME			NUM_ROWS SAMPLE_SIZE ESTIMATE_PERCENT
------------------------------ ------------------------------ ---------- ----------- ----------------
SCOTT			       TEST				   72606       72606		  100


默认大表30%,小表100%

SQL> select count(*) from test where owner='SYS';

  COUNT(*)
----------
     30795

SQL> EXEC DBMS_STATS.gather_table_stats('TEST','TEST');

PL/SQL procedure successfully completed.

SQL> select a.column_name,
       b.num_rows,
       a.num_distinct Cardinality,
       round(a.num_distinct / b.num_rows * 100, 2) selectivity,
       a.histogram,
       a.num_buckets
  from dba_tab_col_statistics a, dba_tables b
 where a.owner = b.owner
   and a.table_name = b.table_name
   and a.owner = 'TEST'
   and a.table_name = 'TEST';
  2    3    4    5    6    7    8    9   10   11  
COLUMN_NAME			 NUM_ROWS CARDINALITY SELECTIVITY HISTOGRAM	  NUM_BUCKETS
------------------------------ ---------- ----------- ----------- --------------- -----------
OWNER				    72530	   30	      .04 FREQUENCY		   24
OBJECT_NAME			    72530	43728	    60.29 NONE			    1
SUBOBJECT_NAME			    72530	  114	      .16 NONE			    1
OBJECT_ID			    72530	72530	      100 NONE			    1
DATA_OBJECT_ID			    72530	 7687	     10.6 NONE			    1
OBJECT_TYPE			    72530	   44	      .06 NONE			    1
CREATED 			    72530	 1093	     1.51 NONE			    1
LAST_DDL_TIME			    72530	 1143	     1.58 NONE			    1
TIMESTAMP			    72530	 1214	     1.67 NONE			    1
STATUS				    72530	    2		0 NONE			    1
TEMPORARY			    72530	    2		0 NONE			    1

COLUMN_NAME			 NUM_ROWS CARDINALITY SELECTIVITY HISTOGRAM	  NUM_BUCKETS
------------------------------ ---------- ----------- ----------- --------------- -----------
GENERATED			    72530	    2		0 NONE			    1
SECONDARY			    72530	    2		0 NONE			    1
NAMESPACE			    72530	   21	      .03 NONE			    1
EDITION_NAME			    72530	    0		0 NONE			    0

15 rows selected.

默认是AUTO 默认的 opt_method 是auto


默认的 采样率 会根据 表大小变化








exec dbms_stats.flush_database_monitoring_info; ----刷新信息到磁盘

--------------EXPLAIN PLAN FOR SQL, 然后执行下面语句得到表名字---------------------------
select '''' || object_owner || '''', '''' || object_name || ''','
  from plan_table
 where object_type = 'TABLE'
union
---table in the index---------
select '''' || table_owner || '''', '''' || table_name || '*'','
  from dba_indexes
 where owner in
       (select distinct object_owner from plan_table where rownum > 0)
   and index_name in
       (select distinct object_name from plan_table where rownum > 0)
order by 2;

--------------再把上面的结果贴入下面代码-------------------------------------------------
select owner, table_name name, object_type, stale_stats, last_analyzed
  from dba_tab_statistics
 where table_name in
(
table_name
)
and owner='owner'
   and (stale_stats = 'YES' or last_analyzed is null);





我现在要查看它怎么过期了
select *
  from all_tab_modifications
 where table_owner='&owner'
   and table_name in
(
'TEST'
)
   and (inserts > 0 or updates > 0 or deletes > 0)
 order by table_name;

原文地址:https://www.cnblogs.com/hzcya1995/p/13352241.html