语法:
DBMS_STATS.GATHER_TABLE_STATS (
ownname VARCHAR2,
tabname VARCHAR2,
partname VARCHAR2,
estimate_percent NUMBER,
block_sample BOOLEAN,
method_opt VARCHAR2,
degree NUMBER,
granularity VARCHAR2,
cascade BOOLEAN,
stattab VARCHAR2,
statid VARCHAR2,
statown VARCHAR2,
no_invalidate BOOLEAN,
force BOOLEAN
);
列含义:
ownname #要分析表的拥有者
tabname #要分析表的表名
partname #分区的名字,只对分区表或者分区索引有用,默认为:null
estimate_percent#采样行的百分比,取值范围[0.000001,100],null是全部分析不采样,常量:DBMS_STATS.AUTO_SAMPLE_SIZE是默认值,由oracle决定最佳取采样值.
block_sample #是否用块采样代替行采样,默认为false
method_opt #method_opt:决定histograms信息是怎样被统计的,统计指定列的直方图时建议使用SKEWONLY
method_opt的取值如下:
for all columns:统计所有列的histograms.
for all indexed columns:统计所有indexed列的histograms.
for all hidden columns:统计你看不到列的histograms
for columns SIZE | REPEAT | AUTO | SKEWONLY
SKEWONLY:统计指定列的histograms.N的取值范围[1,254]
REPEAT上次统计过的histograms
AUTO由oracle决定N的大小
degree #决定并行度,默认为null
granularity #设置分区表收集统计信息的粒度 granularity取值:
all:对表达分区,分区,子分区的数据都做分析
auto:Oracle根据分区的类型,自行决定做哪一种粒 度的分析
global:只做全局级别非分析
global and partition:只对全局和分区级别做分析,对子分区不做分析,这是和all的一个区别
partition:只对分区级别做分析
subpartition:只对子分区做分析
cascade #是收集索引的信息.默认为falase
stattab #指定要存储统计信息的表,
statid #对存储在同一个stattab中的表的统计信息做区分
statown #存储统计信息 表的拥有者
no_invalidate #true:当收集完统计信息后,收集对象的cursor不会失效(不会产生新的执行计划,子游标);
false:当收集完统计信息后,收集对象的cursor会立即失效(新的执行计划,新的子游标)
force #即使表锁定了也收集统计信息
如:execute dbms_stats.gather_table_stats(ownname=>'oracle', tabname=>'tablename', degree=>64, granularity=>'ALL', cascade=>true);
通过上述我们大概了解了GATHER_TABLE_STATS的语法及各参数的含义,但是什么时候使用,他又有什么作用呢?
在这个之前,我们需要了解一下oracle的执行计划:
每一段sql该如何执行,他们都有自己的执行计划。表中的数据量不同,有无索引都会影响他的执行方式,比如我们在收集统计信息时,此时主表数据只有10w条,那么凡是涉及到该主表的sql的执行计划都会
认为该主表的数据量为10w,但是在漫长的使用中,该表的数据量达到了亿级别,此时的执行计划还会认为该表的数据量是10w,所以执行计划就会认为该表只有10w条数据,此时就可能会走了错误的执行计划,
导致该sql长时间无法跑出。此时我们只需要重新收集该表信息后,就会走正确的执行计划。