【工具】show_space

show space

show_space 是由TOM写的一个工具,其实就是一个存储过程,这个存储过程可以用来分析空间使用情况、表的碎片分析,有了此工具,就不用再通过写SQL语句来看每条记录或表占用表空间的大小了,使用起来很方便。

 

脚本如下:

CREATE OR REPLACE PROCEDURE SYSTEM.show_space (

   p_segname    IN  VARCHAR2,

   p_owner      IN  VARCHAR2 DEFAULTUSER,

   p_type       IN  VARCHAR2 DEFAULT'TABLE',

   p_partition  IN  VARCHAR2 DEFAULTNULL

)

-- this procedure uses authid currentuser so it can query DBA_*

-- views using privileges from a ROLE,and so it can be installed

-- once per database, instead of onceper user who wanted to use it

AUTHIDCURRENT_USER

AS

   l_free_blks            NUMBER;

   l_total_blocks         NUMBER;

   l_total_bytes          NUMBER;

   l_unused_blocks        NUMBER;

   l_unused_bytes         NUMBER;

   l_lastusedextfileid    NUMBER;

   l_lastusedextblockid   NUMBER;

   l_last_used_block      NUMBER;

   l_segment_space_mgmt   VARCHAR2 (255);

   l_unformatted_blocks   NUMBER;

   l_unformatted_bytes    NUMBER;

   l_fs1_blocks           NUMBER;

   l_fs1_bytes            NUMBER;

   l_fs2_blocks           NUMBER;

   l_fs2_bytes            NUMBER;

   l_fs3_blocks           NUMBER;

   l_fs3_bytes            NUMBER;

   l_fs4_blocks           NUMBER;

   l_fs4_bytes            NUMBER;

   l_full_blocks          NUMBER;

   l_full_bytes           NUMBER;

-- inline procedure to print outnumbers nicely formatted

-- with a simple label

   PROCEDURE p (p_label IN VARCHAR2, p_num IN NUMBER)

   IS

  BEGIN

      DBMS_OUTPUT.put_line (   RPAD (p_label, 40, '.')

                            || TO_CHAR (p_num, '999,999,999,999'));

   END;

BEGIN

-- this query is executed dynamicallyin order to allow this procedure

-- to be created by a user who hasaccess to DBA_SEGMENTS/TABLESPACES

-- via a role as is customary.

-- NOTE: at runtime, the invoker MUSThave access to these two

-- views!

-- this query determines if the objectis an ASSM object or not

  BEGIN

     EXECUTE IMMEDIATE

        'select ts.segment_space_management

          from dba_segments seg,dba_tablespaces ts

         where seg.segment_name = :p_segname

           and (:p_partition is null

                or seg.partition_name =:p_partition)

           and seg.owner = :p_owner

           and seg.tablespace_name =ts.tablespace_name'

      INTOl_segment_space_mgmt

     USINGp_segname, p_partition,p_partition, p_owner;

  EXCEPTION

      WHEN TOO_MANY_ROWS

      THEN

         DBMS_OUTPUT.put_line

           ('This must be a partitioned table, use p_partition => ');

         RETURN;

   END;

-- if the object is in an ASSMtablespace, we must use this API

-- call to get space information,otherwise we use the FREE_BLOCKS

-- API for the user-managed segments

   IFl_segment_space_mgmt = 'AUTO'

   THEN

      DBMS_SPACE.space_usage

        (p_owner,

         p_segname,

         p_type,

         l_unformatted_blocks,

         l_unformatted_bytes,

         l_fs1_blocks,

         l_fs1_bytes,

         l_fs2_blocks,

         l_fs2_bytes,

         l_fs3_blocks,

         l_fs3_bytes,

         l_fs4_blocks,

         l_fs4_bytes,

         l_full_blocks,

         l_full_bytes,

         p_partition

        );

      p ('Unformatted Blocks ', l_unformatted_blocks);

      p ('FS1 Blocks (0-25) ', l_fs1_blocks);

      p ('FS2 Blocks (25-50) ', l_fs2_blocks);

      p ('FS3 Blocks (50-75) ', l_fs3_blocks);

      p ('FS4 Blocks (75-100)', l_fs4_blocks);

      p ('Full Blocks ', l_full_blocks);

   ELSE

      DBMS_SPACE.free_blocks

        (segment_owner     =>p_owner,

         segment_name      =>p_segname,

         segment_type      =>p_type,

         freelist_group_id => 0,

         free_blks         =>l_free_blks

         );

      p ('Free Blocks', l_free_blks);

  END IF;

-- and then the unused space API callto get the rest of the

-- information

   DBMS_SPACE.unused_space

     (segment_owner             =>p_owner,

      segment_name              =>p_segname,

      segment_type              =>p_type,

      partition_name            =>p_partition,

      total_blocks              =>l_total_blocks,

      total_bytes               =>l_total_bytes,

      unused_blocks             =>l_unused_blocks,

      unused_bytes              =>l_unused_bytes,

      last_used_extent_file_id  =>l_lastusedextfileid,

      last_used_extent_block_id => l_lastusedextblockid,

      last_used_block           =>l_last_used_block

     );

   p ('Total Blocks', l_total_blocks);

   p ('Total Bytes', l_total_bytes);

   p ('Total MBytes', TRUNC (l_total_bytes / 1024 / 1024));

   p ('Unused Blocks', l_unused_blocks);

   p ('Unused Bytes', l_unused_bytes);

   p ('Last Used Ext FileId', l_lastusedextfileid);

   p ('Last Used Ext BlockId', l_lastusedextblockid);

   p ('Last Used Block', l_last_used_block);

END;

/

 

使用方法:

SQL> set serverout on

SQL> exec show_space('T_EPZ_LOCK_HISTORY','EPLOG')

Unformatted Blocks .....................               0            --以下由DBMS_SPACE.space_usage获得

FS1 Blocks (0-25) ......................               0

FS2 Blocks (25-50) .....................               2

FS3 Blocks (50-75) .....................               1

FS4 Blocks (75-100).....................             320

Full Blocks ............................         539,588

Total Blocks............................         540,928          --以下由DBMS_SPACE.unused_space获得

Total Bytes.............................  4,431,282,176

Total MBytes............................           4,226

Unused Blocks...........................               0

Unused Bytes............................               0

Last Used Ext FileId....................              33

Last Used Ext BlockId...................         149,513

Last Used Block.........................             128

 

PL/SQL procedure successfully completed.


你可能感兴趣的:(oracle,存储过程,procedure,show_space)