(一)问题背景
最近在对一个大约200万行数据的表查看执行计划时,发现存在异常,理论上应该返回100多万笔数据的,但是执行计划只返回了2条数据,比较奇怪,稍微思考,肯定是统计信息出问题了。
explain plan for select * from table_***_NOTIFY where be_ID is not null;
查看表的统计信息,发现最后一次收集统计信息是在2018年4月22日,已经是2年前的信息了,已经很久没有收集统计信息了
(二)Oracle什么情况下会自动收集统计信息
Oracle收集失效的统计信息的策略:自上次自动统计信息收集作业完成之后,如果DBA_TAB_MODIFICATIONS中记录的INSERT+UPDATE+DELETE所影响的行记录之和超过了DBA_tableS中目标表记录数的10%,或者是自上次统计信息收集完成之后目标表执行过truncate *** 作,那么Oracle会认为目标表的统计信息已经失效,自动统计信息收集作业就会对目标表重新收集统计信息。
(三)Oracle为什么没有自动收集统计信息
根据上述策略,理论上肯定是要收集统计信息的,那么这里为什么没有收集统计信息呢?
首先想到的是统计信息被关闭了。根据个人经验,在某些公司高并发的业务系统中,统计信息的收集可能会引发异常等待事件,因此会把统计信息关闭,之后要么手动根据DBA_TAB_MODIFICATIONS编写脚本来收集,要么一直不收集,直到执行计划有问题再对单表收集。
那么是不是Oracle的自动统计信息收集功能关闭了呢?查询确认,发现自动统计信息是开启的。
SELECT WINDOW_name,autoTASK_STATUS,OPTIMIZER_STATS,SEGMENT_ADVISOR,sql_TUNE_ADVISOR FROM DBA_autoTASK_WINDOW_CLIENTS ;
既然自动收集统计信息是开启的,那么只有可能是该表的统计信息被锁定了,可以尝试手动收集统计信息
sql> exec dbms_stats.gather_table_stats(ownname => '***',tabname cascade => true);
发现有如下报错,可以确定是统计信息被锁了,由于过去很久,不知道之前是谁把统计信息给锁了,系统也多次换人接手,已经无从查起。
(四)解决办法
既然是统计信息锁了导致无法收集新的统计信息,那么接下来只要解锁并重新收集统计信息即可,方法如下:
--解锁某个表的统计信息EXEC dbms_stats.unlock_table_stats(ownname '); 重新收集某个表的统计信息EXEC dbms_stats.gather_table_stats(ownname => true);还存在一个问题,数据库中可能还存在其他的表也被锁定了统计信息,我如何确认数据库中哪些表的统计信息被锁定:
SELECT owner,table_name,stattype_locked FROM DBA_TAB_STATISTICS a WHERE a.stattype_locked IN (ALLDATACACHE')备注:stattype_locked为空代表统计信息未锁定。
【完】
总结以上是内存溢出为你收集整理的oracle统计信息的锁定与解锁全部内容,希望文章能够帮你解决oracle统计信息的锁定与解锁所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)