1.收集统计信息的方式

  • for all columns size skewonly
BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
                                tabname          => 'TEST',
                                estimate_percent => 100,
                                method_opt       => 'for all columns size skewonly',
                                no_invalidate    => FALSE,
                                degree           => 8,
                                cascade          => TRUE);
END;
/
 
查看统计信息

select a.column_name,
b.num_rows,
a.num_distinct Cardinality,
round(a.num_distinct / b.num_rows * 100, 2) selectivity,
a.histogram,
a.num_buckets
from dba_tab_col_statistics a, dba_tables b
where a.owner = b.owner
and a.table_name = b.table_name
and a.owner = 'SCOTT'
and a.table_name = 'TEST';

method_opt设置成for all columns size skewnoly时,让oracle自动判断是否需要收集直方图,除了主键列和唯一值列之外的列都收集直方图。这不符合我们收集直方图的规则,只有在where关键字之后出现的列才收集直方图。

  • for all columns size auto

创建一个新表,使用auto的方式对表test收集直方图。

BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
                                tabname          => 'TEST',
                                estimate_percent => 100,
                                method_opt       => 'for all columns size auto',
                                no_invalidate    => FALSE,
                                degree           => 8,
                                cascade          => TRUE);
END;
/

查看统计信息

可以看到,当对一个新表使用auto方式收集直方图的时候,num_buckets数为1,说明没有收集直方图

接下来运行sql,在收集直方图

SQL> select count(*) from test where owner='SB';

COUNT(*)
----------
0

exec dbms_stats.flush_database_monitoring_info; --刷新内存

查看where关键字后列值进行过滤操作的信息

select
r.name owner,
o.name table_name ,
c.name column_name,
equality_preds, ---等值过滤
equijoin_preds, ---等值JOIN过滤 比如where a.id=b.id
nonequijoin_preds, ----不等JOIN过滤
range_preds, ----范围过滤 > >= < <= between and
like_preds, ----LIKE过滤
null_preds, ----NULL 过滤
timestamp
from
sys.col_usage$ u,
sys.obj$ o,
sys.col$ c,
sys.user$ r
where
o.obj# = u.obj#
and c.obj# = u.obj#
and c.col# = u.intcol#
and r.name='SCOTT' and o.name='TEST';

通过显示结果可以知道,用户scott下test表中的owner列进行了一次等值连接

再次执行auto模式收集统计信息

BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
                                tabname          => 'TEST',
                                estimate_percent => 100,
                                method_opt       => 'for all columns size auto',
                                no_invalidate    => FALSE,
                                degree           => 8,
                                cascade          => TRUE);
END;
/

查询统计信息

可以看出对owner列收集了直方图,如果有sql运行,有where列,就收集直方图。

使用auto方式收集统计信息也是不可用的,在oracle11g里用没有问题,因为解决了绑定变量窥探的问题,在11g之前使用for all columns size 1方式,遇到需要收集的列单独收集。

  • for all columns size repeat

BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
                                tabname          => 'TEST',
                                estimate_percent => 100,
                                method_opt       => 'for all columns size repeat',
                                no_invalidate    => FALSE,
                                degree           => 8,
                                cascade          => TRUE);
END;
/

这种方式是推荐的方式,对以前收集过的列,进行收集,以前没收集过的,就不收集。

当系统运行稳定的时候采用这种方式收集统计信息。第一次上线的时候先使用for all columns size 1方式收集,在发现运行慢的sql对单独列进行收集统计信息,之后等系统运行稳定,使用repeat方式收集统计信息。

  • for columns <column name> size skewonly

BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
                                tabname          => 'TEST',
                                estimate_percent => 100,
                                method_opt       => 'for columns object_name size skewonly',
                                no_invalidate    => FALSE,
                                degree           => 8,
                                cascade          => TRUE);
END;
/

查看统计信息

可以看到对object_name列单独收集了直方图。

常用的统计信息相关的脚本

1.查看收集统计信息的采样率

SELECT owner,
table_name,
num_rows,
sample_size,
trunc(sample_size / num_rows * 100) estimate_percent
FROM DBA_TAB_STATISTICS
WHERE owner='SCOTT' AND table_name='TEST';

采样率是否合适,根据表的大小而定,根究dba_segments查看表的大小,制定采样率

2G以内采样率为100%

2G-5G采样率为50%

5G-10G采样率为30%

10G-20G采样率为10%

20G-30G采样率为5%

30G以上采样率为1%

2.查看统计信息是否过期

exec dbms_stats.flush_database_monitoring_info;

select owner, table_name name, object_type, stale_stats, last_analyzed
  from dba_tab_statistics
 where table_name in ('TEST')
   and owner = 'SCOTT'
   and (stale_stats = 'YES' or last_analyzed is null);

统计信息过期的标准是,变化率超过10%

如果一个表一年都没有DML操作,是否对他重新收集统计信息呢?不需要,因为统计信息根本没有过期。

3.定制收集统计信息的脚本

DECLARE
  CURSOR STALE_TABLE IS
    SELECT OWNER,
           SEGMENT_NAME,
           CASE
             WHEN SIZE_GB < 2 THEN
              100
             WHEN SIZE_GB >= 2 AND SIZE_GB < 5 THEN
              50
             WHEN SIZE_GB >= 5 AND SIZE_GB < 10 THEN
              30
             WHEN SIZE_GB >= 10 AND SIZE_GB < 30 THEN
              10
             WHEN SIZE_GB >= 30 THEN
              1
           END AS PERCENT,
           8 AS DEGREE
      FROM (SELECT OWNER,
                   SEGMENT_NAME,
                   SUM(BYTES / 1024 / 1024 / 1024) SIZE_GB
              FROM DBA_SEGMENTS
             WHERE OWNER = 'ADWU_OPTIMA_AP11'
               AND SEGMENT_NAME IN
                   (SELECT /*+ UNNEST */ DISTINCT TABLE_NAME
                      FROM DBA_TAB_STATISTICS
                     WHERE (LAST_ANALYZED IS NULL OR STALE_STATS = 'YES')
                       AND OWNER = 'ADWU_OPTIMA_AP11')
             GROUP BY OWNER, SEGMENT_NAME);

BEGIN
  DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;
  FOR STALE IN STALE_TABLE LOOP
    DBMS_STATS.GATHER_TABLE_STATS(OWNNAME          => STALE.OWNER,
                                  TABNAME          => STALE.SEGMENT_NAME,
                                  ESTIMATE_PERCENT => STALE.PERCENT,
                                  METHOD_OPT       => 'for all columns size repeat',
                                  DEGREE           => 8,
                                  GRANULARITY      => 'ALL',--这个是针对分区表,非分区表要进行改写

NO_INVALIDATE   => FALSE,
                                  CASCADE          => TRUE);
  END LOOP;
END;
/

4.DBA_TAB_STATS_HISTORY 可以查看表历史收集统计信息的时间,利用下面脚本分析某个表统计信息收集时间间隔

select owner,
      table_name,
      partition_name,
      subpartition_name,
      stats_update_time,
      stats_update_time - lag(stats_update_time, 1, null) over(partition by owner, table_name order by stats_update_time) interval
 from DBA_TAB_STATS_HISTORY
where owner = 'SCOTT'
  and table_name = 'TEST'
order by owner, table_name, stats_update_time desc;

5.下面SQL是查询 TOP 50 INSERTS,UPDATES,DELETES 的表

select * from
(
select * from 
(
select * from
(
select u.name owner, o.name table_name, null partition_name, null subpartition_name,
       m.inserts, m.updates, m.deletes, m.timestamp,
       decode(bitand(m.flags,1),1,'YES','NO') truncated,
       m.drop_segments
from sys.mon_mods_all$ m, sys.obj$ o, sys.tab$ t, sys.user$ u
where o.obj# = m.obj# and o.obj# = t.obj# and o.owner# = u.user#
union all
select u.name, o.name, o.subname, null,
       m.inserts, m.updates, m.deletes, m.timestamp,
       decode(bitand(m.flags,1),1,'YES','NO'),
       m.drop_segments
from sys.mon_mods_all$ m, sys.obj$ o, sys.user$ u
where o.owner# = u.user# and o.obj# = m.obj# and o.type#=19
union all
select u.name, o.name, o2.subname, o.subname,
       m.inserts, m.updates, m.deletes, m.timestamp,
       decode(bitand(m.flags,1),1,'YES','NO'),
       m.drop_segments
from sys.mon_mods_all$ m, sys.obj$ o, sys.tabsubpart$ tsp, sys.obj$ o2,
     sys.user$ u
where o.obj# = m.obj# and o.owner# = u.user# and
      o.obj# = tsp.obj# and o2.obj# = tsp.pobj#
) where owner not like '%SYS%' and owner not like 'XDB'     
union all 
select * from
(    
select u.name owner, o.name table_name, null partition_name, null subpartition_name,
       m.inserts, m.updates, m.deletes, m.timestamp,
       decode(bitand(m.flags,1),1,'YES','NO') truncated,
       m.drop_segments
from sys.mon_mods$ m, sys.obj$ o, sys.tab$ t, sys.user$ u
where o.obj# = m.obj# and o.obj# = t.obj# and o.owner# = u.user#
union all
select u.name, o.name, o.subname, null,
       m.inserts, m.updates, m.deletes, m.timestamp,
       decode(bitand(m.flags,1),1,'YES','NO'),
       m.drop_segments
from sys.mon_mods$ m, sys.obj$ o, sys.user$ u
where o.owner# = u.user# and o.obj# = m.obj# and o.type#=19
union all
select u.name, o.name, o2.subname, o.subname,
       m.inserts, m.updates, m.deletes, m.timestamp,
       decode(bitand(m.flags,1),1,'YES','NO'),
       m.drop_segments
from sys.mon_mods$ m, sys.obj$ o, sys.tabsubpart$ tsp, sys.obj$ o2,
     sys.user$ u
where o.obj# = m.obj# and o.owner# = u.user# and
      o.obj# = tsp.obj# and o2.obj# = tsp.pobj#
) where owner not like '%SYS%' and owner not like '%XDB%'
) order by inserts desc 
) where rownum<=50;

 
6.关闭oracle自动收集统计信息的job

方法一:

exec dbms_scheduler.disable('SYS.GATHER_STATS_JOB');

exec dbms_scheduler.enable('SYS.GATHER_STATS_JOB');

方法二:

alter system set "_optimizer_autostats_job"=false scope=spfile;

alter system set "_optimizer_autostats_job"=true scope=spfile;

Pfile可以直接修改初始化参数文件,重新启动数据库

 

oracle学习----统计信息的更多相关文章

  1. 验证Oracle收集统计信息参数granularity数据分析的力度

    最近在学习Oracle的统计信息这一块,收集统计信息的方法如下: DBMS_STATS.GATHER_TABLE_STATS ( ownname VARCHAR2, ---所有者名字 tabname ...

  2. ORACLE收集统计信息

    1.     理解什么是统计信息 优化器统计信息就是一个更加详细描述数据库和数据库对象的集合,这些统计信息被用于查询优化器,让其为每条SQL语句选择最佳的执行计划.优化器统计信息包括: ·       ...

  3. ORACLE 收集统计信息

    1.     理解什么是统计信息优化器统计信息就是一个更加详细描述数据库和数据库对象的集合,这些统计信息被用于查询优化器,让其为每条SQL语句选择最佳的执行计划.优化器统计信息包括: ·        ...

  4. Oracle自动统计信息的收集原理及实验

    [日期:2014-11-21]来源:Linux社区  作者:stevendbaguo[字体:大 中 小] 从Oracle Database 10g开始,Oracle在建库后就默认创建了一个名为GATH ...

  5. Oracle 搜集统计信息

    常用的统计信息收集脚本: 非分区表: BEGIN   DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',             ...

  6. Oracle Statistic 统计信息 小结

    oraclestatisticstabledatabasesqldictionary   目录(?)[-] 直方图上列的信息说明 直方图类型说明   一.  Statistic 说明 Oracle 官 ...

  7. oracle的统计信息的查看与收集

    查看某个表的统计信息 SQL> alter session set NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'; Session altered. SQL&g ...

  8. Oracle备份统计信息

    Oracle可以通过DBMS_STATS.GET_TABLE_STATS 收集表的统计信息,一般的收集方法如下: DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => ...

  9. Oracle 11G统计信息自动收集及调整

    查询统计信息的收集所对应的task,以及当前状态 col CLIENT_NAME for a50col TASK_NAME for a20SELECT client_name, task_name, ...

随机推荐

  1. javascript 字符串转数字

    //把str转换为数字的方式,想起很久以前的一个面试题,说字符转数字的方式有哪些,现在想了想 var str1='4.88',str2='4.8xx'; console.log(parseInt(st ...

  2. python邮件收发SAMPLE

    #!/usr/bin/env python # -*- encoding: utf-8 -*- import os, socket from time import localtime, strfti ...

  3. HTML input标签的checked属性与Razor解析

    在HTML中,input标签可以通过type属性设置为checkbox.同时,也就包含了一个checked属性.对于这个checked属性,有一个特别的地方就是,它可以不需要属性值就可以表示是否选择了 ...

  4. 数据挖掘十大经典算法(5) 最大期望(EM)算法

    在统计计算中,最大期望(EM,Expectation–Maximization)算法是在概率(probabilistic)模型中寻找参数最大似然估计的算法,其中概率模型依赖于无法观测的隐藏变量(Lat ...

  5. java的版本区别、下载、配置

    参考:http://blog.csdn.net/liujun13579/article/details/7684604 java的版本区别 常用的 java 程序分为  Java SE.Java EE ...

  6. WordPress NOSpam PTI插件‘comment_post_ID’参数SQL注入漏洞

    漏洞名称: WordPress NOSpam PTI插件‘comment_post_ID’参数SQL注入漏洞 CNNVD编号: CNNVD-201309-388 发布时间: 2013-09-24 更新 ...

  7. sql server 2008中id如何设为自增

    通过 IDENTITY 来设置 参数有2个,一个是“初始值” 一个是“增量”.默认情况下 INSERT 语句中,不能对 IDENTITY 的字段进行赋值. create table web_produ ...

  8. js前台与后台数据交互-后台调前台(后台调用、注册客户端脚本)

    转自:http://blog.csdn.net/wang379275614/article/details/17049721 客户端脚本一般都在前台,这里讲的是(1)在后台调用前台定义的脚本(2)在后 ...

  9. ASP.NET学习路线图

    转自:http://www.cnblogs.com/huangmeimujin/archive/2011/08/08/2131242.html 如果你已经有较多的面向对象开发经验,跳过以下这两步: 第 ...

  10. PowerDesigner 怎么给 Table Properties 增加注释和默认值

    1.  选中表,右键 2. 选中“comment”, 这个就是列的注释 3.还是这个页面 ,往下有个“default value”, 这个就是你设置的默认值. 4. 这个是怎么设置默认值.