oracle統計資訊(三)

安佰勝發表於2011-02-28

 

8. 收集統計資訊的一些例子
例子1對錶收集統計資訊

BEGIN
   DBMS_STATS.GATHER_TABLE_STATS(ownname => 'SCOTT',
                                 tabname => 'DEPT',
                                 estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
                                 method_opt => 'for all columns size repeat',
                                 degree => DBMS_STATS.AUTO_DEGREE,
                                 cascade=>TRUE
                                 );
END;
/

上面的例子收集SCOTT.DEPT表的統計資訊。這裡面值得關注的一個引數就是method_opt。這個引數控制是否收集列的直方圖資訊。通常情況下,是不會收集直方圖的.

關於直方圖不是三言兩語可以說明白的。

它的四個選項

 

method_opt=>'for all columns size skewonly' 

ORACLE會根據資料分佈收集直方圖

 

method_opt=>'for all columns size repeat'

只有以前收集過直方圖,才會收集直方圖資訊,所以一般我們會設定method_opt repeat

 

method_opt=>'for all columns size auto' 

ORACLE會根據資料分佈以及列的workload來確定是否收集直方圖

method_opt=>'for all columns size interger'

我們自己指定一個bucket

例子2對某一個schma收集統計資訊
BEGIN

   DBMS_STATS.GATHER_SCHEMA_STATS(ownname => 'SCOTT',

                                  estimate_percent =>DBMS_STATS.AUTO_SAMPLE_SIZE,

                                  ptions => 'gather auto',

                                  degree  => DBMS_STATS.AUTO_DEGREE,

                                  method_opt => 'for all columns size repeat',

                                  cascade => TRUE

                                 );

END;                                

/

 

上面的例子收集SCOTT模式下所有物件的統計資訊。裡面值得注意的一個引數就是options。前面已經講到過,他與表監控有關。它有四個選項

Options =>’gather’       收集所有物件的統計資訊
Options =>’gather empty’
只收集還沒被統計的表
Options =>’gather stale’
只收集修改量超過10%的表
Options =>’gather auto’ 
相當於empty+stale ,所以我們一般設定為AUTO

例子3 對一個分割槽表收集統計資訊
BEGIN
   DBMS_STATS.GATHER_TABLE_STATS(ownname => 'ROBINSON',
                                 tabname => 'P_TEST',
                                 estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
                                 method_opt => 'for all columns size repeat',
                                 degree => DBMS_STATS.AUTO_DEGREE,

                                 granularity => 'ALL',
                                 cascade=>TRUE
                                 );
END;
/

 

上面的例子收集ROBINSON.P_TEST表的統計資訊。裡面值得注意的一個引數就是granularity,他有7個選項。

 

granularity => 'ALL'  收集分割槽,子分割槽,全域性的統計資訊
granularity => 'AUTO'
這個是預設的設定,ORACLE會根據分割槽型別來決定用ALL,GLOBAL AND PARTITION ,還是其他的
granularity => 'DEFAULT'
這個是過期了的
granularity => 'GLOBAL'
收集全域性統計資訊
granularity => 'GLOBAL AND PARTITION'
收集全域性,分割槽統計資訊,但是不收集子分割槽統計資訊
granularity => 'PARTITION'
收集分割槽統計資訊
granularity => 'SUBPARTITION'
收集子分割槽統計資訊
當然我們可以指定partname,自己控制對哪個分割槽收集統計資訊

 

9. 列出表需要收集統計資訊的指令碼

普通表

set serveroutput on

declare

   -----select OVER THE Change RATE TABLES---------------

   cursor overchangerate is

 select a.table_owner, a.table_name, a.inserts,a.updates,a.deletes ,b.num_rows

                from dba_tab_modifications a, dba_tables b

               where a.table_name = b.table_name

                 and table_owner not in

                     ('SYS', 'SYSTEM', 'SYSMAN', 'DMSYS', 'OLAPSYS', 'XDB',

                      'EXFSYS', 'CTXSYS', 'WMSYS', 'DBSNMP', 'ORDSYS',

                      'OUTLN', 'TSMSYS', 'MDSYS')

                 and inserts > 0 and partitioned='NO' and a.inserts/decode(b.num_rows,0,1,b.num_rows)>=0.1

                 or a.table_name = b.table_name

                 and table_owner not in

                     ('SYS', 'SYSTEM', 'SYSMAN', 'DMSYS', 'OLAPSYS', 'XDB',

                      'EXFSYS', 'CTXSYS', 'WMSYS', 'DBSNMP', 'ORDSYS',

                      'OUTLN', 'TSMSYS', 'MDSYS')

                 and updates > 0 and partitioned='NO' and a.updates/decode(b.num_rows,0,1,b.num_rows)>=0.1 or

                 a.table_name = b.table_name

                 and table_owner not in

                     ('SYS', 'SYSTEM', 'SYSMAN', 'DMSYS', 'OLAPSYS', 'XDB',

                      'EXFSYS', 'CTXSYS', 'WMSYS', 'DBSNMP', 'ORDSYS',

                      'OUTLN', 'TSMSYS', 'MDSYS')

                 and deletes > 0 and partitioned='NO' and a.deletes/decode(b.num_rows,0,1,b.num_rows)>=0.1 ;

    ----select the unanalyzed table---------------

    cursor nullmonitor is

      select owner, table_name

        from dba_tables

       where owner not in ('SYS', 'SYSTEM', 'SYSMAN', 'DMSYS', 'OLAPSYS',

              'XDB', 'EXFSYS', 'CTXSYS', 'WMSYS', 'DBSNMP',

              'ORDSYS', 'OUTLN', 'TSMSYS', 'MDSYS')

         and last_analyzed is null;

  begin

    dbms_output.enable(1000000);

    ----flush the monitorring information into the dba_tab_modifications

    DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;

    ----display the unanalyzed table--------------

    dbms_output.put_line('- - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');

  

    dbms_output.put_line('Unalalyzed tables:');

    for v_null in nullmonitor loop

      dbms_output.put_line(v_null.owner || '.' || v_null.table_name ||

                           ' has not been analyzed, consider gathering statistics');

    end loop;

    ----display the  information-------------------

    dbms_output.put_line('- - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' );

    dbms_output.put_line('Over the Change_Rate 10%:');

    for v_topinsert in overchangerate loop

      dbms_output.put_line(v_topinsert.table_owner || '.' || v_topinsert.table_name || ' once has ' || v_topinsert.num_rows || ' rows, ' ||

                           'till now inserted ' || v_topinsert.inserts || ' rows, updated  ' || v_topinsert.updates || ' rows, deleted ' || v_topinsert.deletes ||   

                           ' rows. consider gathering statistics');

    end loop;

     dbms_output.put_line('- - - - - - - - - - - - - - - - - - -  - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');

  end;

/

 

下面的是分割槽表
set serveroutput on

declare

   -----select OVER THE Change RATE TABLES---------------

   cursor overchangerate is

select a.table_owner,a.table_name,a.partition_name,sum(a.inserts) inserts,sum(a.updates) updates,sum(a.deletes) deletes,sum(b.num_rows) num_rows

from dba_tab_modifications a,dba_tab_partitions b where a.table_owner =b.table_owner and a.table_name=b.table_name

and a.partition_name=b.partition_name and   a.table_owner not in ('SYS', 'SYSTEM', 'SYSMAN', 'DMSYS', 'OLAPSYS', 'XDB',

'EXFSYS', 'CTXSYS', 'WMSYS', 'DBSNMP', 'ORDSYS','OUTLN', 'TSMSYS', 'MDSYS')

group by a.table_owner,a.table_name,a.partition_name

having (sum(a.inserts)/decode(sum(b.num_rows),0,1,sum(b.num_rows)))>=0.1

or

(sum(a.updates)/decode(sum(b.num_rows),0,1,sum(b.num_rows)))>=0.1

or

(sum(a.deletes)/decode(sum(b.num_rows),0,1,sum(b.num_rows)))>=0.1

order by a.table_name;

  begin

    dbms_output.enable(1000000);

    ----flush the monitorring information into the dba_tab_modifications

    DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;

    ----display the top_n_insert information-------------------

    dbms_output.put_line('- - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' );

    dbms_output.put_line('Over the Change_Rate 10%:');

    for v_topinsert in overchangerate loop

      dbms_output.put_line(v_topinsert.table_owner || '.' || v_topinsert.table_name || ' partition ' || v_topinsert.partition_name  || ' once has ' || v_topinsert.num_rows || ' rows, ' ||

                           'till now inserted ' || v_topinsert.inserts || ' rows, updated  ' || v_topinsert.updates || ' rows, deleted ' || v_topinsert.deletes ||   

                           ' rows. consider gathering statistics');

    end loop;

    dbms_output.put_line('- - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' );

  end;

/

 

在此特別宣告一點,在oracle11.2版本中有一個相關的BUG

Bug 9272549 - User statistics are ignored when dynamic sampling occurs 9272549.8

BUG會導致嚴重的效能問題。

oracle官方申明,只有在12.1版本才解決這個問題,臨時解決方案是手動關閉動態取樣。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13177610/viewspace-688099/,如需轉載,請註明出處,否則將追究法律責任。

相關文章