Wednesday 16 July 2014

How to find High water mark in Oracle 11g Database

---For Multiple Tables

SET LINESIZE 300
SET SERVEROUTPUT ON
SET VERIFY OFF

DECLARE
  CURSOR cu_tables IS
    SELECT a.owner,
           a.table_name
    FROM   all_tables a
    WHERE  a.table_name = Decode(Upper('&&Table_Name'),'ALL',a.table_name,Upper('&&Table_Name'))
    AND    a.owner      = Upper('ORCL') 
    AND    a.partitioned='NO'
    AND    a.logging='YES'
order by table_name;

  op1  NUMBER;
  op2  NUMBER;
  op3  NUMBER;
  op4  NUMBER;
  op5  NUMBER;
  op6  NUMBER;
  op7  NUMBER;
BEGIN

  Dbms_Output.Disable;
  Dbms_Output.Enable(1000000);
  Dbms_Output.Put_Line('TABLE                             UNUSED BLOCKS     TOTAL BLOCKS  HIGH WATER MARK');
  Dbms_Output.Put_Line('------------------------------  ---------------  ---------------  ---------------');
  FOR cur_rec IN cu_tables LOOP
    Dbms_Space.Unused_Space(cur_rec.owner,cur_rec.table_name,'TABLE',op1,op2,op3,op4,op5,op6,op7);
    Dbms_Output.Put_Line(RPad(cur_rec.table_name,30,' ') ||
                         LPad(op3,15,' ')                ||
                         LPad(op1,15,' ')                ||
                         LPad(Trunc(op1-op3-1),15,' ')); 
  END LOOP;

END;
/

-----------When One Table---


SET LINESIZE 300
SET SERVEROUTPUT ON
SET VERIFY OFF

DECLARE
  CURSOR cu_tables IS
    SELECT a.owner,
           a.table_name
    FROM   all_tables a
    WHERE  a.table_name = Decode(Upper('STCHELAN'),'ALL',a.table_name,Upper('STCHELAN'))
    AND    a.owner      = Upper('ORCL') 
    AND    a.partitioned='NO'
    AND    a.logging='YES'
order by table_name;

  op1  NUMBER;
  op2  NUMBER;
  op3  NUMBER;
  op4  NUMBER;
  op5  NUMBER;
  op6  NUMBER;
  op7  NUMBER;
BEGIN

  Dbms_Output.Disable;
  Dbms_Output.Enable(1000000);
  Dbms_Output.Put_Line('TABLE                             UNUSED BLOCKS     TOTAL BLOCKS  HIGH WATER MARK');
  Dbms_Output.Put_Line('------------------------------  ---------------  ---------------  ---------------');
  FOR cur_rec IN cu_tables LOOP
    Dbms_Space.Unused_Space(cur_rec.owner,cur_rec.table_name,'TABLE',op1,op2,op3,op4,op5,op6,op7);
    Dbms_Output.Put_Line(RPad(cur_rec.table_name,30,' ') ||
                         LPad(op3,15,' ')                ||
                         LPad(op1,15,' ')                ||
                         LPad(Trunc(op1-op3-1),15,' ')); 
  END LOOP;

END;
/


---------------------------------
SQL> select blocks, empty_blocks, num_rows  from  dba_tables  where table_name='STCHELAN' and owner='ORCL';

    BLOCKS EMPTY_BLOCKS   NUM_ROWS
---------- ------------ ----------
       478         9762      13435

SQL>

blocks+Empty_blocks=478+9762=10240  ( but   not   8)   because  1 block  is  for   segment   header .

SQL> select blocks,extents from dba_segments where segment_type='TABLE' and segment_name='STCHELAN'  and owner='ORCL';

    BLOCKS    EXTENTS
---------- ----------
     10240          3

SQL>


SQL> select   count ( distinct   dbms_rowid.rowid_block_number (rowid) )   "used blocks"  from STLBAS.STCHELAN;

used blocks
-----------
        444


SQL> select   count(distinct dbms_rowid.rowid_block_number(rowid)|| '-' | | dbms_rowid.rowid_relative_fno(rowid)) " used  blocks"   from ORCL.STCHELAN;

 used  blocks
--------------
           444

SQL>

Solution : To reduce high water mark we can use one of below three steps

Step1: Shrink space 

ALTER  TABLE  ORCL.STCHELAN enable ROW MOVEMENT;

ALTER  TABLE  ORCL.STCHELAN SHRINK  SPACE;

Step2: Move particular table

ALTER  TABLE  ORCL.STCHELAN move;

Note: Rebuld all indexes of above table

Step3: Export/Import particular table


No comments:

Post a Comment