• oracle统计信息的锁定与解锁


    image


    (一)问题背景

    最近在对一个大约200万行数据的表查看执行计划时,发现存在异常,理论上应该返回100多万笔数据的,但是执行计划只返回了2条数据,比较奇怪,稍微思考,肯定是统计信息出问题了。

    explain plan for select * from TABLE_***_NOTIFY where be_id is not null;

    clipboard

    查看表的统计信息,发现最后一次收集统计信息是在2018年4月22日,已经是2年前的信息了,已经很久没有收集统计信息了

    clipboard


    (二)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 ;

    clipboard

    既然自动收集统计信息是开启的,那么只有可能是该表的统计信息被锁定了,可以尝试手动收集统计信息

    SQL> exec dbms_stats.gather_table_stats(ownname => '***',tabname => '***',cascade => true);

    发现有如下报错,可以确定是统计信息被锁了,由于过去很久,不知道之前是谁把统计信息给锁了,系统也多次换人接手,已经无从查起。

    clipboard


    (四)解决办法

    既然是统计信息锁了导致无法收集新的统计信息,那么接下来只要解锁并重新收集统计信息即可,方法如下:

    --解锁某个表的统计信息
    EXEC dbms_stats.unlock_table_stats(ownname => '***',tabname => '***'); 
    
    --重新收集某个表的统计信息
    EXEC dbms_stats.gather_table_stats(ownname => '***',tabname => '***',cascade => true);


    还存在一个问题,数据库中可能还存在其他的表也被锁定了统计信息,我如何确认数据库中哪些表的统计信息被锁定:

    SELECT owner,table_name,stattype_locked FROM DBA_TAB_STATISTICS a WHERE a.stattype_locked IN ('ALL','DATA','CACHE')

    备注:stattype_locked为空代表统计信息未锁定。


    【完】

  • 相关阅读:
    OpenCV使用边缘提取、腐蚀、轮廓进行车牌定位
    How To Move Or Rebuild A Lob Partition
    Hadoop入门进阶步步高(三)-配置Hadoop
    [学习笔记]整体DP
    leetcode404
    leetcode349
    leetcode383
    leetcode453
    leetcode455
    leetcode167
  • 原文地址:https://www.cnblogs.com/lijiaman/p/13039589.html
Copyright © 2020-2023  润新知