方案概述

Oracle11g推出了增量(incremental)统计信息收集新特性,提高大表统计信息收集的效率问题。
不同分区方式情况下,incremental和非incremental方式统计信息收集比较:
范围分区:
incremental和非Incremental的方式收集,之间的效率差异主要一是在分区数,如果分区的数量越多,二者的差异越明显,incremental明显占优势;二是Insert的数据量所占的分区数,如果所占分区数越多,Incremental的优势会慢慢被非incremental赶超,最终,如果是insert的数据占用了全分区,incremental不如非incremental
hash分区
incremental和非Incremental的方式收集,和range分区表的行为差异很大,并没有出现incremental很快,非incremental很慢的情况,且两种方式均随着数据量和分区数的增加,收集所消耗时间都增加。且基本是非incremental的方式快于incremental的方式。
总得来说,incremental的方式收集分区的统计信息比较适合于有多个分区,且变动分区比较少的分区,如range分区。而对于hash分区来说,由于没有范围界限,在理想状态下,数据是均匀分布到每个分区的,新load数据几乎平均load到每个分区,因此每个分区都是有变动的。

1.请确认以下开启增量统计信息的条件
1)分区表的PUBLISH设为true
2)分区表的INCREMENTAL设为true
3)AUTO_SAMPLE_SIZE设为ESTIMATE_PERCENT
4)GRANULARITY设为AUTO

2.对表进行表级别的统计信息收集,统计信息收集完成后分别检查表和分区的统计信息收集时间
收集完成后相关静态分区统计信息收集时间不会随着表的统计信息收集而改变。


实施步骤

收集策略调整

注:收集策略根据自己需要调整
收集方式:

SQL> select dbms_stats.GET_PREFS ('METHOD_OPT') FROM DUAL;

DBMS_STATS.GET_PREFS('METHOD_OPT')
------------------------------------------------------------
FOR ALL COLUMNS SIZE AUTO   

# 修改为size repeat方式
SQL> exec dbms_stats.set_global_prefs('METHOD_OPT','FOR ALL COLUMNS SIZE REPEAT');

PL/SQL procedure successfully completed.

触发阈值(默认10%)

SQL> SELECT DBMS_STATS.GET_PREFS(pname=>'STALE_PERCENT',ownname=>'CCPS',tabname=>'CREDITINFO_PART') FROM DUAL;

DBMS_STATS.GET_PREFS(PNAME=>'STALE_PERCENT',OWNNAME=>'CCPS',TABNAME=>'CREDITINFO_PART')
-------------------------------------------------------------------------------------
10

# 修改为5%
SQL> exec dbms_stats.set_table_prefs('CCPS','CREDITINFO_PART','STALE_PERCENT',5);

PL/SQL procedure successfully completed.

还有其它很多策略参数可以修改,可以是针对库级修改,也可以是表级修改,具体可以参考

https://docs.oracle.com/en/database/oracle/oracle-database/12.2/arpls/DBMS_STATS.html#GUID-01FAB8ED-E4A3-4C3E-8FE2-88717DCDDA06

修改为增量收集

SQL> exec dbms_stats.set_table_prefs('CCPS','CREDITINFO_PART','INCREMENTAL','TRUE');

PL/SQL procedure successfully completed.

重启统计信息收集任务

SQL> begin
DBMS_AUTO_TASK_ADMIN.DISABLE(client_name => 'auto optimizer stats collection',
operation => NULL,
window_name => NULL);
end;
/

PL/SQL procedure successfully completed.

SQL> begin
DBMS_AUTO_TASK_ADMIN.ENABLE(client_name => 'auto optimizer stats collection',
operation => NULL,
window_name => NULL);
end;
/

PL/SQL procedure successfully completed.