2023年11月29日发(作者:)
ORACLE表空间和表碎⽚分析及整理⽅法
表空间碎⽚率
idle> select pace_name,sqrt(max()/sum())*(100/sqrt(sqrt(count()))) FSFI
from dba_free_space a,dba_tablespaces b
where pace_name=pace_name
and ts not in ('TEMPORARY','UNDO')
group by pace_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 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_;
loop
fetch query into this_row;
exit when query%notfound;
if this__id = previous__id + previous_ then
total := total + this_;
insert into SPACE_TEMP (tablespace_name)
values (previous_pace_name);
else
insert into SPACE_TEMP values (previous_pace_name,
total);
total := this_;
end if;
previous_row := this_row;
end loop;
insert into SPACE_TEMP values (previous_pace_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_
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"
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导出后,重新导⼊重建,在重新创建索引和重新收集统计信息。
技术
1. create table newtable as select * from old_table
2. drop old_table
3. rename table newtable to old_table
4. 重建索引,收集统计信息。
tablespace
sql> alter table <表名> move tablespace <表空间名>
重建索引,收集统计信息。
Redefinition
这个较前⼏种有点复杂,⽽且实施的时候需要考虑oracle bug,稍后进⾏介绍。


发布评论