zoukankan      html  css  js  c++  java
  • 找出需要分析的表以及delete超过阀值(你设定)的表

    自己编写的一个小脚本,找出没有被analyzed的表,插入条数top 5,删除条数 top 5的表,以及delete 超过阀值的表,该脚本对ORACLE性能没有多大影响,放心使用吧。

    注意,每当我们对表搜集一次统计信息之后,如果该表没有insert,delete操作,此脚本将无法查询出任何条目

    create or replace Function tablespace(segment_owner varchar2, segment_name varchar2)
        return varchar2 as
        total_blocks  number;
        total_bytes   number;
        unused_blocks number;
        unused_bytes  number;
        luefi         number;
        luebi         number;
        lub           number;
      begin
        dbms_space.unused_space(segment_name              => segment_name,
                                segment_owner             => segment_owner,
                                segment_type              => 'TABLE',
                                total_blocks              => total_blocks,
                                total_bytes               => total_bytes,
                                unused_blocks             => unused_blocks,
                                unused_bytes              => unused_bytes,
                                last_used_extent_file_id  => luefi,
                                last_used_extent_block_id => luebi,
                                last_used_block           => lub);
        return segment_owner || '.' || segment_name || ' has ' || total_blocks || ' blocks,' ||(total_blocks -
                                                                                                unused_blocks) || ' used,' || unused_blocks || ' unused.';
      end tablespace;

    运行下面脚本之前需要创建上面的函数


    declare
                         top_n_inserts number :=5;
                         top_n_deletes number :=5;
                         top_n_updates number :=5;
                         delete_rate   number :=20;
        cursor topinsert is
          select *
            from (select a.table_owner, a.table_name, sum(a.inserts) inserts
                    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
                   group by a.table_owner, a.table_name
                   order by inserts desc)
           where rownum <= top_n_inserts;
        -----select top_n_updates---------------
        cursor topupdate is
          select *
            from (select a.table_owner, a.table_name, sum(a.updates) updates
                    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 updates > 0
                   group by a.table_owner, a.table_name
                   order by updates desc)
           where rownum <= top_n_updates;
        ----select top_n_deletes----------------
        cursor topdelete is
          select *
            from (select a.table_owner, a.table_name, sum(a.deletes) deletes
                    from dba_tab_modifications a, dba_tables b
                   where a.table_name = b.table_name
                     and a.table_owner not in
                         ('SYS', 'SYSTEM', 'SYSMAN', 'DMSYS', 'OLAPSYS', 'XDB',
                          'EXFSYS', 'CTXSYS', 'WMSYS', 'DBSNMP', 'ORDSYS',
                          'OUTLN', 'TSMSYS', 'MDSYS')
                     and deletes > 0
                   group by a.table_owner, a.table_name
                   order by deletes desc)
           where rownum <= top_n_deletes;
        ----select the detail information about the table------------
        cursor monitor is
          select b.owner, b.table_name, inserts, deletes, num_rows
            from (select table_owner,
                         table_name,
                         sum(inserts) inserts,
                         sum(updates) updates,
                         sum(deletes) deletes
                    from dba_tab_modifications
                   group by table_owner, table_name) a,
                 dba_tables b
           where a.table_owner = b.owner
             and a.table_name = b.table_name
             and b.owner not in ('SYS', 'SYSTEM', 'SYSMAN', 'DMSYS', 'OLAPSYS',
                  'XDB', 'EXFSYS', 'CTXSYS', 'WMSYS', 'DBSNMP',
                  'ORDSYS', 'OUTLN', 'TSMSYS', 'MDSYS')
             and b.last_analyzed is not null;
        ----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 top_n_insert information-------------------
        dbms_output.put_line('- - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' );
        dbms_output.put_line('Top ' || top_n_inserts || ' Inserts:');
        for v_topinsert in topinsert loop
          dbms_output.put_line(tablespace(v_topinsert.table_owner,
                                          v_topinsert.table_name) ||
                               ' Inserted ' || v_topinsert.inserts || ' rows,' ||
                               'consider gathering statistics');
        end loop;
        ----display the top_n_update informaation----------------
        dbms_output.put_line('- - - - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');
        dbms_output.put_line('Top ' || top_n_updates || ' Updates:');
        for v_topupdate in topupdate loop
          dbms_output.put_line(tablespace(v_topupdate.table_owner,
                                          v_topupdate.table_name) ||
                               ' Updated ' || v_topupdate.updates || ' rows,' ||
                               'consider gathering statistics');
        end loop;
        ---display the top_n_deletes information-----------------
        dbms_output.put_line('- - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');
        dbms_output.put_line('Top ' || top_n_deletes || ' Deletes:');
        for v_topdelete in topdelete loop
          dbms_output.put_line(tablespace(v_topdelete.table_owner,
                                          v_topdelete.table_name) ||
                               ' Deleted ' || v_topdelete.deletes || ' rows,' ||
                               'consider gathering statistics');
        end loop;
        ---display the table which should be shrinked--------------
        dbms_output.put_line('- - - - - - - - - - - - - - - - - - -  - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');
        dbms_output.put_line('Over the Delete_Rate ' || delete_rate || '%:');
        for v_monitor in monitor loop
          if (v_monitor.deletes - v_monitor.inserts) > 0 then
            if (v_monitor.num_rows + v_monitor.inserts - v_monitor.deletes) = 0 then
              dbms_output.put_line(tablespace(v_monitor.owner,
                                              v_monitor.table_name) || ' Has ' ||
                                   (v_monitor.num_rows + v_monitor.inserts -
                                    v_monitor.deletes) || ' rows now,' ||
                                   (v_monitor.deletes - v_monitor.inserts) ||
                                   ' rows deleted.consider  shirnking the table!!! ');
            elsif (v_monitor.deletes - v_monitor.inserts) /
                  (v_monitor.num_rows + v_monitor.inserts - v_monitor.deletes) >=
                  delete_rate / 100 then
              dbms_output.put_line(tablespace(v_monitor.owner,
                                              v_monitor.table_name) || ' Has ' ||
                                   (v_monitor.num_rows + v_monitor.inserts -
                                    v_monitor.deletes) || ' rows now,' ||
                                   round((v_monitor.deletes -
                                         v_monitor.inserts) /
                                         (v_monitor.num_rows +
                                         v_monitor.inserts -
                                         v_monitor.deletes),
                                         4) * 100 ||
                                   '% of the table has been deleted' ||
                                   ',consider shirnking the table!!!');
            end if;
          else
            if (v_monitor.deletes) / (v_monitor.inserts + v_monitor.num_rows) >=
               (delete_rate / 100) then
              dbms_output.put_line(tablespace(v_monitor.owner,
                                              v_monitor.table_name) || ' Has ' ||
                                   (v_monitor.num_rows + v_monitor.inserts -
                                    v_monitor.deletes) || ' rows now,' ||
                                   round((v_monitor.deletes) /
                                         (v_monitor.num_rows +
                                         v_monitor.inserts),
                                         4) * 100 ||
                                   '% of the table has been deleted' ||
                                   ',consider shirnking the table!!!');
            end if;
          end if;
        end loop;
         dbms_output.put_line('- - - - - - - - - - - - - - - - - - -  - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');
      end;
    /

    例子:
    SQL> /
    - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Unalalyzed tables:
    ROBINSON.CONS has not been analyzed,consider gathering statistics
    ROBINSON.CONS1 has not been analyzed,consider gathering statistics
    - - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Top 5 Inserts:
    - - - - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Top 5 Updates:
    - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Top 5 Deletes:
    ROBINSON.TEST has 768 blocks,707 used,61 unused. Deleted 49970 rows,consider gathering statistics
    - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Over the Delete_Rate 20%:
    ROBINSON.TEST has 768 blocks,707 used,61 unused. Has 0 rows now,49970 rows deleted.consider  shirnking the table!!!

    PL/SQL procedure successfully completed

     可以刻使用下面的脚本,下面这个脚本不需要运行上面的函数

     set serveroutput on
    declare
                         top_n_inserts number :=5;
                         top_n_deletes number :=5;
                         top_n_updates number :=5;
                         delete_rate   number :=20;
        cursor topinsert is
          select *
            from (select a.table_owner, a.table_name, sum(a.inserts) inserts,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
                   group by a.table_owner, a.table_name,b.num_rows
                   order by inserts desc)
           where rownum <= top_n_inserts;
        -----select top_n_updates---------------
        cursor topupdate is
          select *
            from (select a.table_owner, a.table_name, sum(a.updates) updates,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 updates > 0
                   group by a.table_owner, a.table_name,b.num_rows
                   order by updates desc)
           where rownum <= top_n_updates;
        ----select top_n_deletes----------------
        cursor topdelete is
          select *
            from (select a.table_owner, a.table_name, sum(a.deletes) deletes,b.num_rows
                    from dba_tab_modifications a, dba_tables b
                   where a.table_name = b.table_name
                     and a.table_owner not in
                         ('SYS', 'SYSTEM', 'SYSMAN', 'DMSYS', 'OLAPSYS', 'XDB',
                          'EXFSYS', 'CTXSYS', 'WMSYS', 'DBSNMP', 'ORDSYS',
                          'OUTLN', 'TSMSYS', 'MDSYS')
                     and deletes > 0
                   group by a.table_owner, a.table_name,b.num_rows
                   order by deletes desc)
           where rownum <= top_n_deletes;
        ----select the detail information about the table------------
        cursor monitor is
          select b.owner, b.table_name, inserts, deletes, num_rows
            from (select table_owner,
                         table_name,
                         sum(inserts) inserts,
                         sum(updates) updates,
                         sum(deletes) deletes
                    from dba_tab_modifications
                   group by table_owner, table_name) a,
                 dba_tables b
           where a.table_owner = b.owner
             and a.table_name = b.table_name
             and b.owner not in ('SYS', 'SYSTEM', 'SYSMAN', 'DMSYS', 'OLAPSYS',
                  'XDB', 'EXFSYS', 'CTXSYS', 'WMSYS', 'DBSNMP',
                  'ORDSYS', 'OUTLN', 'TSMSYS', 'MDSYS')
             and b.last_analyzed is not null;
        ----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 top_n_insert information-------------------
        dbms_output.put_line('- - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' );
        dbms_output.put_line('Top ' || top_n_inserts || ' Inserts:');
        for v_topinsert in topinsert 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,' ||
                               'consider gathering statistics');
        end loop;
        ----display the top_n_update informaation----------------
        dbms_output.put_line('- - - - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');
        dbms_output.put_line('Top ' || top_n_updates || ' Updates:');
        for v_topupdate in topupdate loop
          dbms_output.put_line(v_topupdate.table_owner || '.' || v_topupdate.table_name || ' once has ' || v_topupdate.num_rows || ' rows, ' ||
                               'till now updated ' || v_topupdate.updates || ' rows,' ||
                               'consider gathering statistics');
        end loop;
        ---display the top_n_deletes information-----------------
        dbms_output.put_line('- - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');
        dbms_output.put_line('Top ' || top_n_deletes || ' Deletes:');
        for v_topdelete in topdelete loop
          dbms_output.put_line(v_topdelete.table_owner || '.' || v_topdelete.table_name || ' once has ' || v_topdelete.num_rows || ' rows, ' ||
                               'till now deleted ' || v_topdelete.deletes || ' rows,' ||
                               'consider gathering statistics');
        end loop;
        ---display the table which should be shrinked--------------
        dbms_output.put_line('- - - - - - - - - - - - - - - - - - -  - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');
        dbms_output.put_line('Over the Delete_Rate ' || delete_rate || '%:');
        for v_monitor in monitor loop
          if (v_monitor.deletes - v_monitor.inserts) > 0 then
            if (v_monitor.num_rows + v_monitor.inserts - v_monitor.deletes) = 0 then
              dbms_output.put_line(v_monitor.owner || '.' ||
                                              v_monitor.table_name || ' Has ' ||
                                   (v_monitor.num_rows + v_monitor.inserts -
                                    v_monitor.deletes) || ' rows now,' ||
                                   (v_monitor.deletes - v_monitor.inserts) ||
                                   ' rows deleted.consider  shirnking the table!!! ');
            elsif (v_monitor.deletes - v_monitor.inserts) /
                  (v_monitor.num_rows + v_monitor.inserts - v_monitor.deletes) >=
                  delete_rate / 100 then
              dbms_output.put_line(v_monitor.owner || '.' ||
                                              v_monitor.table_name || ' Has ' ||
                                   (v_monitor.num_rows + v_monitor.inserts -
                                    v_monitor.deletes) || ' rows now,' ||
                                   round((v_monitor.deletes -
                                         v_monitor.inserts) /
                                         (v_monitor.num_rows +
                                         v_monitor.inserts -
                                         v_monitor.deletes),
                                         4) * 100 ||
                                   '% of the table has been deleted' ||
                                   ',consider shirnking the table!!!');
            end if;
          else
            if (v_monitor.deletes) / (v_monitor.inserts + v_monitor.num_rows) >=
               (delete_rate / 100) then
              dbms_output.put_line(v_monitor.owner || '.' ||
                                              v_monitor.table_name || ' Has ' ||
                                   (v_monitor.num_rows + v_monitor.inserts -
                                    v_monitor.deletes) || ' rows now,' ||
                                   round((v_monitor.deletes) /
                                         (v_monitor.num_rows +
                                         v_monitor.inserts),
                                         4) * 100 ||
                                   '% of the table has been deleted' ||
                                   ',consider shirnking the table!!!');
            end if;
          end if;
        end loop;
         dbms_output.put_line('- - - - - - - - - - - - - - - - - - -  - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');
      end;
    /

    例子:

    SQL> /
    - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Unalalyzed tables:
    ROBINSON.CONS has not been analyzed,consider gathering statistics
    ROBINSON.CONS1 has not been analyzed,consider gathering statistics
    - - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Top 5 Inserts:
    ROBINSON.TEST once has 49970 rows, till now inserted 49969 rows,consider gathering statistics
    - - - - - - - - - - - - - - - - - - - - - - -  - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Top 5 Updates:
    - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Top 5 Deletes:
    ROBINSON.TEST once has 49970 rows, till now deleted 49970 rows,consider gathering statistics
    - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Over the Delete_Rate 20%:
    - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    PL/SQL procedure successfully completed

  • 相关阅读:
    Feign调用文件上传服务接口样例
    Feign调用文件下载服务接口样例
    使用Spring Security的Basic Auth认证后Postman的POST请求不成功的可能原因
    Spring Boot应用的Controller返回的集合类数据是XML格式的可能原因
    Eureka Server增加Spring Security后的服务端和客户端配置
    Spring Data支持的关键字
    JPA(Hibernate)代理类的hibernateLazyInitializer属性系列化异常
    Spring Boot中fastjson的@JSONField(format = "yyyy-MM-dd HH:mm:ss")失效可能原因
    使用Java代码配置MyBatis Generator
    CentOS8.1中搭建Nexus3服务器
  • 原文地址:https://www.cnblogs.com/hehe520/p/6330644.html
Copyright © 2011-2022 走看看