Script to Report Table Fragmentation (Doc ID 1019716.6)
Applies to:
Oracle Database - Enterprise Edition - Version 7.3.0.0 and laterOracle Database Cloud Schema Service - Version N/A and later
Gen 1 Exadata Cloud at Customer (Oracle Exadata Database Cloud Machine) - Version N/A and later
Oracle Database Exadata Express Cloud Service - Version N/A and later
Oracle Cloud Infrastructure - Database Service - Version N/A and later
Information in this document applies to any platform.
Goal
Provide a script to report table fragmentation. Note: This script is still useful at 10.2 in that it gives a detailed report of block usage etc. This note makes no claims about how to remedy table fragmentation. The methods you can use to do this vary depending on whether ASSM is in use etc. A simpler note is Note 337651.1 How to find Objects Fragmented below High water mark.
Solution
| Abstract | |
| This script will report table fragmentation. | |
Product Name, Product Version | Oracle Server, 7.3 to 9.2.0 |
|---|---|
| Platform | Platform Independent |
| Date Created | 16-Jul-1996 |
| Instructions | |
Execution Environment:
SQL, SQL*Plus
Access Privileges:
Requires user with SELECT privileges on DBA_TABLES, DBA_SEGMENTS, DBA_EXTENTS
and ANALYZE privilege on table.
Usage:
sqlplus <user>/<password> @<script_name>
where <script_name> is one of the following scripts.
Instructions:
Copy the scripts to different files and execute them from SQL*Plus.
PROOFREAD THIS SCRIPT BEFORE USING IT! Due to differences in the way text
editors, e-mail packages, and operating systems handle text formatting (spaces,
tabs, and carriage returns), this script may not be in an executable state
when you first receive it. Check over the script to ensure that errors of
this type are corrected.NOTE: In the images and/or the document content below, the user information and environment data used represents fictitious data from the Oracle sample or bulit-in schema(s), Public Documentation delivered with an Oracle database product or other training material. Any similarity to actual environments, actual persons, living or dead, is purely coincidental and not intended in any manner. | |
| Description | |
The first script, TFSLDTFR.SQL, gathers table fragmentation characteristics and inserts it into the newly created TFRAG table for subsequent reporting. TFSLDTFR performs a single "analyze table 't' compute statistics" command. You may want to change the compute to estimate for speed and usability. Currently the following characteristics are gathered: - Owner of table. - Name of table - Number of data blocks with rows - Number of table extents - Number of chained rows - Number of blocks that have ever contained a row (high water mark) Scripts two and three display table fragmentation information. The information is queried from the TFRAG table which is created during script one. | |
| References | |
| Script | |
=============
First Script:
=============
SET ECHO off
REM NAME: TFSLDTFR.SQL
REM USAGE:"@path/tfsldtr table_owner table_name"
REM ------------------------------------------------------------------------
REM REQUIREMENTS:
REM ANALYZE on table, SELECT on DBA_TABLES, DBA_SEGMENTS, DBA_EXTENTS
REM ------------------------------------------------------------------------
REM AUTHOR:
REM Oracle US
REM ------------------------------------------------------------------------
REM PURPOSE:
REM Load the tfrag table with a given table's fragmentation stats.
REM ------------------------------------------------------------------------
REM EXAMPLE:
REM N/A
REM ------------------------------------------------------------------------
REM DISCLAIMER:
REM This script is provided for educational purposes only. It is NOT
REM supported by Oracle World Wide Technical Support.
REM The script has been tested and appears to work as intended.
REM You should always run new scripts on a test instance initially.
REM ------------------------------------------------------------------------
REM Main text of script follows:
set feedback on
set echo on
set verify off
def towner=&1
def tname=&2
rem *******************************************************************
rem * Goal: Analyze table to gather statistics
rem *******************************************************************
rem Specifically we are looking for:
rem - blocks ABOVE the hwm, i.e. empty blocks (dba_tables.blocks)
rem - average row length (dba_tables.blocks)
analyze table &towner..&tname compute statistics
/
col val1 new_value blks_w_rows noprint
col val2 new_value blks_above noprint
select blocks val1,
empty_blocks val2
from dba_tables
where owner = upper('&towner') and
table_name = upper('&tname')
/
rem *******************************************************************
rem * Goal: Get the number of blocks allocated to the segment
rem *******************************************************************
rem Specifically we are looking for:
rem - allocated blocks dba_segments.blocks
col val1 new_value alloc_blocks noprint
select blocks val1
from dba_segments
where owner = upper('&towner') and
segment_name = upper('&tname')
/
rem *******************************************************************
rem * Goal: Calculate the HWM
rem *******************************************************************
rem Specifically we are looking for:
rem HWM = dba_segments.blocks - dba_tables.empty_blocks - 1
rem HWM = allocated blocks - blocks above the hwn - 1
col val1 new_value hwm noprint
select &alloc_blocks-&blks_above-1 val1
from dual
/
rem *******************************************************************
rem * Goal: Get the Number of Fragmented Rows or Chained Frows (cr)
rem *******************************************************************
col val1 new_value cr noprint
select chain_cnt val1
from dba_tables
where owner = upper('&towner') and
table_name = upper('&tname')
/
rem ***********************************************************
rem * Goal : Determine the Segment Fragmentation (sf)
rem ***********************************************************
col val1 new_val sf noprint
select count(*) val1
from dba_extents
where owner = upper('&towner') and
segment_name = upper('&tname')
/
rem ***********************************************************
rem ***********************************************************
rem * Load the TFRAG table with the just gathered information.
rem ***********************************************************
rem ***********************************************************
rem *
rem * Create the tfrag table if it does not exist.
rem *
drop table tfrag;
create table tfrag
(
owner char(30),
name char(30),
hwm number,
blks_w_rows number,
avg_row_size number,
possible_bytes_per_block number,
no_frag_rows number,
no_extents number
)
/
create unique index tfrag_u1 on tfrag (owner,name)
/
rem *
rem * Delete and insert the new stats.
rem *
delete
from tfrag
where owner='&towner' and
name='&tname'
/
insert into tfrag values
('&towner','&tname',&hwm,&blks_w_rows,0,0,&cr,&sf)
/
commit;
set echo off
set verify on
==============
Second Script:
==============
SET ECHO off
REM NAME: TFSTFRAG.SQL
REM USAGE:"@path/tfstfrag"
REM ------------------------------------------------------------------------
REM REQUIREMENTS:
REM SELECT on TFRAG
REM ------------------------------------------------------------------------
REM AUTHOR:
REM Oracle USA
REM ------------------------------------------------------------------------
REM PURPOSE:
REM This script displays summary table fragmentation information. The
REM information is queried from the tfrag table which is loaded via the
REM ldtfrag script. Once the ldtfrag script has been run for a given
REM table, this report displays the following information:
REM
REM - Table owner
REM - Table name
REM - Segment fragmentation (number of extents)
REM - Number of table rows
REM - Table block fragmentation (1.0 bad, 0.0 good)
REM - Row fragmentation (chains)
REM ------------------------------------------------------------------------
REM EXAMPLE:
REM Table Fragmentation Characteristics
REM
REM Owner Table Name Exts Omega1 Chains
REM -------- ---------------------------------------- ---- ------ -------
REM scott s_emp 1 0.000 0
REM ------------------------------------------------------------------------
REM DISCLAIMER:
REM This script is provided for educational purposes only. It is NOT
REM supported by Oracle World Wide Technical Support.
REM The script has been tested and appears to work as intended.
REM You should always run new scripts on a test instance initially.
REM ------------------------------------------------------------------------
REM Main text of script follows:
col towner heading 'Owner' format a8 trunc
col tname heading 'Table Name' format a40 trunc
col exts heading 'Exts' format 999 trunc
col omega1 heading 'Omega1' format 0.999 trunc
col chains heading 'Chains' format 99,990 trunc
ttitle -
center 'Table Fragmentation Characteristics' skip 2
select owner towner,
name tname,
no_extents exts,
(hwm - blks_w_rows)/(hwm + 0.0001) omega1,
no_frag_rows chains
from tfrag
order by 1,2
/
===========================================
Sample Output from the tfstfrag.sql script:
===========================================
Table Fragmentation Characteristics
Owner Table Name Exts Omega1 Chains
-------- ---------------------------------------- ---- ------ -------
scott s_emp1 0.000 0
=============
Third Script:
=============
SET ECHO off
REM NAME: TFSDTFRG.SQL
REM USAGE:"@path/tfsdtfrg"
REM ------------------------------------------------------------------------
REM REQUIREMENTS:
REM SELECT on TFRAG table created by TFSLDTFR.SQL
REM ------------------------------------------------------------------------
REM AUTHOR:
REM Oracle US
REM ------------------------------------------------------------------------
REM PURPOSE:
REM Detailed report of table fragmentation characteristics based on the
REM data in the tfrag table.
REM ------------------------------------------------------------------------
REM EXAMPLE:
REM Detailed Table Fragmentation Characteristics
REM
REM
REM Table Owner : scott
REM Name : s_emp
REM Extents : 1
REM High water mark : 1
REM Blocks with rows : 1
REM Block frag: Omega1 : 0
REM Migrated rows : 0
REM
REM ------------------------------------------------------------------------
REM DISCLAIMER:
REM This script is provided for educational purposes only. It is NOT
REM supported by Oracle World Wide Technical Support.
REM The script has been tested and appears to work as intended.
REM You should always run new scripts on a test instance initially.
REM ------------------------------------------------------------------------
REM Main text of script follows:
col towner format a70
col tname format a70
col exts format 999
col omega1 format 90.9999
col chains format 99,990
col rpb format 999
col hwm format 9,999,999
col bwr format 9,999,999
ttitle -
center 'Detailed Table Fragmentation Characteristics' skip 2
set heading off
select 'Table Owner : '||owner towner,
' Name : '||name tname,
'Extents : '||no_extents exts,
'High water mark : '||hwm hwm,
'Blocks with rows : '||blks_w_rows bwr,
'Block frag: Omega1 : '||(hwm - blks_w_rows)/(hwm + 0.0001) omega1,
'Migrated rows : '||no_frag_rows chains
from tfrag
order by 1,2
/
set heading on
=========================================== Sample Output from the tfsdtfrg.sql script: =========================================== | |
| Disclaimer | |
EXCEPT WHERE EXPRESSLY PROVIDED OTHERWISE, THE INFORMATION, SOFTWARE, PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS. ORACLE EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ORACLE MAKES NO WARRANTY THAT: (A) THE RESULTS THAT MAY BE OBTAINED FROM THE USE OF THE SOFTWARE WILL BE ACCURATE OR RELIABLE; OR (B) THE INFORMATION, OR OTHER MATERIAL OBTAINED WILL MEET YOUR EXPECTATIONS. ANY CONTENT, MATERIALS, INFORMATION OR SOFTWARE DOWNLOADED OR OTHERWISE OBTAINED IS DONE AT YOUR OWN DISCRETION AND RISK. ORACLE SHALL HAVE NO RESPONSIBILITY FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR LOSS OF DATA THAT RESULTS FROM THE DOWNLOAD OF ANY CONTENT, MATERIALS, INFORMATION OR SOFTWARE. ORACLE RESERVES THE RIGHT TO MAKE CHANGES OR UPDATES TO THE SOFTWARE AT ANY TIME WITHOUT NOTICE. | |
| Limitation of Liability | |
IN NO EVENT SHALL ORACLE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE, DATA OR USE, INCURRED BY YOU OR ANY THIRD PARTY, WHETHER IN AN ACTION IN CONTRACT OR TORT, ARISING FROM YOUR ACCESS TO, OR USE OF, THE SOFTWARE. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY. ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU. | |
| | |
Comments
Post a Comment