使用手工更新的场景:
1. Oracle有个自动更新统计信息的Job,大约在每天晚上执行。所以在白天统计信息不会被更新掉;
2. 统计信息对CBO的影响有个阀值,尤其是对范围查找来说,超过这个阀值,就使用索引,否则就全表扫描;
这时可以使用手工更新来纠正统计信息的错误。
oracle统计值查看
select * from dba_tables where table_name = TABLE
检查一下字段last_analyzed 的值,其值就是最后一次统计更新的日期
手工更新方法:analyze 和 gather_table_stats
全表分析
完全计算法: analyzetable abc compute statistics;
抽样估算法(抽样20%): analyze table abc estimate statistics sample 20 percent;
对表作完全计算所花的时间相当于做全表扫描,抽样估算法由于采用抽样,比完全计算法的生成统计速度要快,如果不是要求要有精确数据的话,尽量采用抽样分析法。建议对表分析采用抽样估算,对索引分析可以采用完全计算。
使用dbms_stats
exec dbms_stats.gather_table_stats(OWNNAME=>'tccs',tabname=>'emp',cascade=>true);
在我们经常做表的分析时会看到使用dbms_stats和analyze在这个方面也会有点不同。
就是当使用dbms_stats来分析表的时候global_stats是YES,而用analyze来分析表的时候就是NO.
而且num_rows结果也会有些不同
那如果我想把一个机器的统计信息干到另一个机器上,怎么来实现这个导出在导入的过程呢?
创建保存字典统计信息表
exec dbms_stats.create_stat_table(USER, 'STAT_TAB', 'TS_DATA');
导出统计信息
exec dbms_stats.export_table_stats(USER, 'TODO', NULL, 'STAT_TAB', NULL, TRUE);
导入统计信息
exec dbms_stats.import_database_stats(USER, 'TODO', stattab=>'STAT_TAB');
database ,schema等级别的dbms_stats里有类似的
dbms_stats.import_database_stats等,可自行看.
有待考证语句:
execute dbms_stats.GATHER_SCHEMA_STATS('用户名',DBMS_STATS.AUTO_SAMPLE_SIZE)
语句来源http://www.itpub.net/thread-704222-1-1.html