ORACLE表空间和表碎片分析及整理方法

表空间碎片率

idle> select a.tablespace_name,sqrt(max(a.blocks)/sum(a.blocks))*(100/sqrt(sqrt(count(a.blocks)))) FSFI
from dba_free_space a,dba_tablespaces b
where a.tablespace_name=b.tablespace_name
and b.contents not in ('TEMPORARY','UNDO')
group by a.tablespace_name 
order by 2;

TABLESPACE_NAME                      FSFI
------------------------------ ----------
EAM                            2.57604251
ALM                            20.1734462
SYSAUX                         22.2842767
SYSTEM                         23.7809729
USERS                           53.439579
RECCAT                                100
ARCH                                  100

7 rows selected.

idle> 

数字越小,表空间碎片较多,当小于30%的时候说明碎片程度很可观了。

按照表空间显示连续的空闲时间

引用官方的一段话:

The ideal situation is to have one large free extent in your tablespace. The more extents of free space there are in the tablespace, the more likely you will run into fragmentation problems. The size of the free extents is also very important. If you have a lot of small extents (too small for any next extent size) but the total bytes of free space is large, then you may want to consider defragmentation options.

脚本中统计了连续空间及对连续空间求和,当表中的总的free空间很大时,但有很多小块,说明碎片化越严重。

========
Script : tfstsfgm
========
SET ECHO off 
REM NAME:TFSTSFRM.SQL 
REM USAGE:"@path/tfstsfgm" 
REM ------------------------------------------------------------------------ 
REM REQUIREMENTS: 
REM    SELECT ON DBA_FREE_SPACE 
REM ------------------------------------------------------------------------ 
REM PURPOSE: 
REM    The following is a script that will determine how many extents 
REM    of contiguous free space you have in Oracle as well as the  
REM total amount of free space you have in each tablespace. From  
REM    these results you can detect how fragmented your tablespace is.  
REM   
REM    The ideal situation is to have one large free extent in your  
REM    tablespace. The more extents of free space there are in the  
REM    tablespace, the more likely you  will run into fragmentation  
REM    problems. The size of the free extents is also  very important.  
REM    If you have a lot of small extents (too small for any next   
REM    extent size) but the total bytes of free space is large, then  
REM    you may want to consider defragmentation options.  
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: 

create table SPACE_TEMP (   
 TABLESPACE_NAME        CHAR(30),   
 CONTIGUOUS_BYTES       NUMBER)   
/   

declare   
  cursor query is select *   
          from dba_free_space   
                  order by tablespace_name, block_id;   
  this_row        query%rowtype;   
  previous_row    query%rowtype;   
total           number;   

begin   
  open query;   
  fetch query into this_row;   
  previous_row := this_row;   
  total := previous_row.bytes;   
  loop   
 fetch query into this_row;   
     exit when query%notfound;   
     if this_row.block_id = previous_row.block_id + previous_row.blocks then   
        total := total + this_row.bytes;   
        insert into SPACE_TEMP (tablespace_name)   
                  values (previous_row.tablespace_name);   
     else   
        insert into SPACE_TEMP values (previous_row.tablespace_name,   
               total);   
        total := this_row.bytes;   
     end if;   
previous_row := this_row;   
  end loop;   
  insert into SPACE_TEMP values (previous_row.tablespace_name,   
                           total);   
end;   
.   
/   

set pagesize 60   
set newpage 0   
set echo off   
ttitle center 'Contiguous Extents Report'  skip 3   
break on "TABLESPACE NAME" skip page duplicate   
spool contig_free_space.lis   
rem   
column "CONTIGUOUS BYTES"       format 999,999,999   
column "COUNT"                  format 999   
column "TOTAL BYTES"            format 999,999,999   
column "TODAY"   noprint new_value new_today format a1   
rem   
select TABLESPACE_NAME  "TABLESPACE NAME",   
       CONTIGUOUS_BYTES "CONTIGUOUS BYTES"   
from SPACE_TEMP   
where CONTIGUOUS_BYTES is not null   
order by TABLESPACE_NAME, CONTIGUOUS_BYTES desc;   

select tablespace_name, count(*) "# OF EXTENTS",   
         sum(contiguous_bytes) "TOTAL BYTES"    
from space_temp   
group by tablespace_name;   

spool off   

drop table SPACE_TEMP   
/  

表空间级别整理方法

对于ASSM管理的表空间,一般都是由smon进程自动整理,前提是表空间的pctincrease值为非0,可以将表空间的缺省存储参数pctincrease改为非0,一般将其设为1。如修改temp表空间的pctincrease属性:alter tablespace temp default storage(pctincrease 1); 这样就可以自动整理表空间级别的碎片整理了。

如果对于字典管理的表空间,可以用下面的命令进行整理:
sql> alter tablespace <表空间名> collesce;

表级别碎片整理方法

1.首选shrink


SQL> alter table t1 enable row movement; --打开行移动
表已更改。 

SQL> alter table t1 shrink space cascade; --压缩表及相关数据段并下调HWM

SQL> alter table t1 shrink space compact; --只压缩不下调HWM

SQL> alter table t1 shrink space ; --下调HWM

SQL> alter table t1 disable row movement; --关闭行移动

只能在ASSM、本地管理的表空间进行,完成这些之后不需要进行索引的重建,但统计信息最好重新收集下,脚本参加本博客上上篇。^_^

2.导入导出

用exp/imp导出后,重新导入重建,在重新创建索引和重新收集统计信息。

3.CATS技术

  1. create table newtable as select * from old_table
  2. drop old_table
  3. rename table newtable to old_table
  4. 重建索引,收集统计信息。

4.move tablespace

sql> alter table <表名> move tablespace <表空间名>
重建索引,收集统计信息。

5.Online Redefinition

这个较前几种有点复杂,而且实施的时候需要考虑oracle bug,稍后进行介绍。

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贤时间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值