Professional Documents
Culture Documents
Table Fragmentation
Table Fragmentation
The first thing we have to do is, we have to analyze the table by using ANALYZE TABLE<TNAME>
COMPUTE STATISTICS;
After that we have to check thetable name called dba_tables column called chain_cnt if the value of
chain_cnt>0 the table is fragmented.keep in mind that we came to know this only after analyzing the
particular table by using ANALYZE.. cmd. before go to the analyzing we check when the corresponding
table has analyzed by the table dba_tables column is last_analyzed.
Table fragmentation
When rows are not stored contiguously, or if rows are split onto more
than one block, performance decreases because these rows require
additional block accesses.
Note that table fragmentation is different from file fragmentation. When
a lot of DML operations are applied on a table, the table will become
fragmented because DML does not release free space from the table
below the HWM.
HWM is an indicator of USED BLOCKS in the database. Blocks below the
high water mark (used blocks) have at least once contained data. This
data might have been deleted. Since Oracle knows that blocks beyond the
high water mark don't have data, it only reads blocks up to the high water
mark when doing a full table scan.
DDL statement always resets the HWM.
How to find table fragmentation?
SQL> select count(*) from big1;
1000000 rows selected.
SQL> delete from big1 where rownum <= 300000;
size
------------------------------ ----------------------------------------BIG1
30604.2kb
Table altered.
SQL> select status,index_name from user_indexes
2 where table_name = 'BIG1';
STATUS INDEX_NAME
-------- -----------------------------UNUSABLE BIGIDX
SQL> alter index bigidx rebuild;
Index altered.
SQL> select status,index_name from user_indexes
2 where table_name = 'BIG1';
STATUS INDEX_NAME
-------- -----------------------------VALID BIGIDX
SQL> exec
dbms_stats.gather_table_stats('SCOTT','BIG1');
PL/SQL procedure successfully completed.
table as select
SQL> create table big2 as select * from big1;
Table created.
TABLE_NAME size
------------------------------ ----------------------------------------BIG1 68986.97kb
SQL> select status from user_indexes
2 where table_name = 'BIG1';
no rows selected
SQL> --Note we need to create all indexes.
Option: 3 "export / truncate / import"
SQL> select table_name, round((blocks*8),2)||'kb'
"size"
2 from user_tables
3 where table_name = 'BIG1';
TABLE_NAME size
------------------------------ ----------------------------------------BIG1 85536kb
SQL> select table_name,
round((num_rows*avg_row_len/1024),2)||'kb' "size"
2 from user_tables
3 where table_name = 'BIG1';
TABLE_NAME size
------------------------------ ----------------------------------------BIG1 42535.54kb
SQL> select status from user_indexes where table_name =
'BIG1';
STATUS
-------VALID
SQL> exit
Disconnected from Oracle Database 10g Enterprise
Edition Release 10.1.0.5.0 - Pr
oduction
With the Partitioning, OLAP and Data Mining options
C:\>exp scott/tiger@Orcl file=c:\big1.dmp tables=big1
Export: Release 10.1.0.5.0 - Production on Sat Jul 28
16:30:44 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> exit
Disconnected from Oracle Database 10g Enterprise
Edition Release 10.1.0.5.0 - Pr
oduction
With the Partitioning, OLAP and Data Mining options
C:\>imp scott/tiger@Orcl file=c:\big1.dmp ignore=y
Import: Release 10.1.0.5.0 - Production on Sat Jul 28
16:31:54 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition
Release 10.1.0.5.0 - Produc
tion
With the Partitioning, OLAP and Data Mining options
Export file created by EXPORT:V10.01.00 via
conventional path
import done in WE8MSWIN1252 character set and AL16UTF16
NCHAR character set
. importing SCOTT's objects into SCOTT
. . importing table "BIG1" 468904 rows imported
Import terminated successfully without warnings.
C:\>sqlplus scott/tiger@orcl
SQL*Plus: Release 10.1.0.5.0 - Production on Sat Jul 28
16:32:21 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release
10.1.0.5.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> select table_name, round((blocks*8),2)||'kb'
"size"
2 from user_tables
3 where table_name = 'BIG1';
TABLE_NAME size
------------------------------ ----------------------------------------BIG1 85536kb
SQL> select table_name,
round((num_rows*avg_row_len/1024),2)||'kb' "size"
2 from user_tables
3 where table_name = 'BIG1';
TABLE_NAME size
------------------------------ ----------------------------------------BIG1 42535.54kb
SQL> exec
dbms_stats.gather_table_stats('SCOTT','BIG1');
PL/SQL procedure successfully completed.
SQL> select table_name, round((blocks*8),2)||'kb'
"size"
2 from user_tables
3 where table_name = 'BIG1';
TABLE_NAME size
------------------------------ ----------------------------------------BIG1 51840kb
SQL> select table_name,
round((num_rows*avg_row_len/1024),2)||'kb' "size"
2 from user_tables
3 where table_name = 'BIG1';
TABLE_NAME size
Table altered.
SQL> begin
for x in 1..100000 loop
insert into table1 ( no , name, ddate)
values ( x , default, default);
end loop;
end;
/
PL/SQL procedure successfully completed.
SQL> create or replace trigger tri_table1
2 after insert on table1
3 begin
4 null;
5 end;
6 /
Trigger created.
SQL> select count(*) from table1;
COUNT(*)
---------100000
TABLE_NAME size
------------------------------ ----------------------------------------TABLE1 822.69kb
3 begin
4 null;
5 end;
6 /
Trigger created.
SQL> --Disable foreign key on original table if exists
before finish this proces
s.
SQL>
SQL> exec sys.dbms_redefinition.finish_redef_table (
'SCOTT',> 'TABLE1',> 'TABLE2');
PL/SQL procedure successfully completed.
SQL> exec
dbms_stats.gather_table_stats('SCOTT','TABLE1');
PL/SQL procedure successfully completed.
SQL> select table_name, round((blocks*8),2)||'kb'
"size"
2 from user_tables
3 where table_name = 'TABLE1';
TABLE_NAME size
------------------------------ ----------------------------------------TABLE1 1376kb
SQL> select table_name,
round((num_rows*avg_row_len/1024),2)||'kb' "size"
2 from user_tables
3 where table_name = 'TABLE1';
TABLE_NAME size
------------------------------ ----------------------------------------TABLE1 841.4kb
SQL> select status,constraint_name
2 from user_constraints
3 where table_name = 'TABLE1';
STATUS CONSTRAINT_NAME
-------- -----------------------------ENABLED PK_NO1
SQL> select status ,trigger_name
2 from user_triggers
3 where table_name = 'TABLE1';
STATUS TRIGGER_NAME
-------- -----------------------------ENABLED TRI_TABLE2
SQL> drop table TABLE2 PURGE;
Table dropped.
http://dbataj.blogspot.com/2007/07/table-fragmentation.html
Many Thanks!
Regards,
Deep
where table_name='T';
TABLE_NAME
TABLESIZE ACTUALSIZE
2320
6658.21
Table altered.
SQL> exec dbms_stats.gather_table_stats('SYSTEM','T');
PL/SQL procedure successfully completed.
SQL> select table_name, round((blocks*8),2) tablesize,
round((num_rows*avg_row_l
en/1024),2) actualsize from dba_tables
2
where table_name='T';
TABLE_NAME
TABLESIZE ACTUALSIZE
7344
6658.21