▲能让表“瘦身”吗?▲

xxiao07 2006-01-19 07:24:56
我的一个表很胖,达到20G了!!我将2年前的数据DELETE,估计有30%的记录被DELETE了,但表所占的空间是不会小下来的。

想通过新建一个表(Create table Newtbl as select * from oldtbl),再删除“旧表”已经没有“地盘”了,因为预计新表也有14G,而我只有5G的硬盘空间了。

------------------------------------------------------------------------------
有什么命令可以让表直接“瘦身”?谢谢!

...全文
225 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
sanoul 2006-01-25
  • 打赏
  • 举报
回复
ORACLE碎片整理

我们知道, Oracle 作为一种大型数据库,广泛应用于金融、邮电、电力、民航等数据吞吐量巨大,计算机网络广泛普及的重要部门。对于系统管理员来讲,如何保证网络稳定运行,如何提高数据库性能,使其更加安全高效,就显得尤为重要。作为影响数据库性能的一大因素 -- 数据库碎片,应当引起 DBA 的足够重视,及时发现并整理碎片乃是 DBA 一项基本维护内容。

1 、碎片是如何产生的

---- 当生成一个数据库时,它会分成称为表空间( Tablespace )的多个逻辑段( Segment ),如系统( System )表空间 , 临时( Temporary )表空间等。一个表空间可以包含多个数据范围( Extent )和一个或多个自由范围块,即自由空间( Free Space )。

---- 表空间、段、范围、自由空间的逻辑关系如下:

---- 当表空间中生成一个段时,将从表空间有效自由空间中为这个段的初始范围分配空间。在这些初始范围充满数据时,段会请求增加另一个范围。这样的扩展过程会一直继续下去,直到达到最大的范围值,或者在表空间中已经没有自由空间用于下一个范围。最理想的状态就是一个段的数据可被存在单一的一个范围中。这样,所有的数据存储时靠近段内其它数据,并且寻找数据可少用一些指针。但是一个段包含多个范围的情况是大量存在的,没有任何措施可以保证这些范围是相邻存储的,如图〈 1 〉。当要满足一个空间要求时,数据库不再合并相邻的自由范围(除非别无选择), 而是寻找表空间中最大的自由范围来使用。这样将逐渐形成越来越多的离散的、分隔的、较小的自由空间,即碎片。例如:

2 、碎片对系统的影响

---- 随着时间推移,基于数据库的应用系统的广泛使用,产生的碎片会越来越多,将对数据库有以下两点主要影响:

---- ( 1 )导致系统性能减弱

---- 如上所述,当要满足一个空间要求时,数据库将首先查找当前最大的自由范围,而 " 最大 " 自由范围逐渐变小,要找到一个足够大的自由范围已变得越来越困难,从而导致表空间中的速度障碍,使数据库的空间分配愈发远离理想状态;

---- ( 2 )浪费大量的表空间

---- 尽管有一部分自由范围(如表空间的 pctincrease 为非 0 )将会被 SMON (系统监控)后台进程周期性地合并,但始终有一部分自由范围无法得以自动合并,浪费了大量的表空间。

3 、自由范围的碎片计算

---- 由于自由空间碎片是由几部分组成,如范围数量、最大范围尺寸等,我们可用 FSFI--Free Space Fragmentation Index (自由空间碎片索引)值来直观体现:

FSFI=100*SQRT(max(extent)/sum(extents))*1/SQRT(SQRT(count(extents)))

---- 可以看出, FSFI 的最大可能值为 100 (一个理想的单文件表空间)。随着范围的增加, FSFI 值缓慢下降,而随着最大范围尺寸的减少, FSFI 值会迅速下降。

---- 下面的脚本可以用来计算 FSFI 值:

rem FSFI Value Compute

rem fsfi.sql

column FSFI format 999,99

select tablespace_name,sqrt(max(blocks)/sum(blocks))*

(100/sqrt(sqrt(count(blocks)))) FSFI

from dba_free_space

group by tablespace_name order by 1;

spool fsfi.rep;

/

spool off;

---- 比如,在某数据库运行脚本 fsfi.sql, 得到以下 FSFI 值:

TABLESPACE_NAME FSFI

------------------------------ -------

RBS 74.06

SYSTEM 100.00

TEMP 22.82

TOOLS 75.79

USERS 100.00

USER_TOOLS 100.00

YDCX_DATA 47.34

YDCX_IDX 57.19

YDJF_DATA 33.80

YDJF_IDX 75.55

---- 统计出了数据库的 FSFI 值,就可以把它作为一个可比参数。在一个有着足够有效自由空间,且 FSFI 值超过 30 的表空间中,很少会遇见有效自由空间的问题。当一个空间将要接近可比参数时,就需要做碎片整理了。

4 、自由范围的碎片整理

---- ( 1 )表空间的 pctincrease 值为非 0

---- 可以将表空间的缺省存储参数 pctincrease 改为非 0 。一般将其设为 1 ,如:

alter tablespace temp

default storage(pctincrease 1);

---- 这样 SMON 便会将自由范围自动合并。也可以手工合并自由范围:

alter tablespace temp coalesce;

5 、段的碎片整理

---- 我们知道,段由范围组成。在有些情况下,有必要对段的碎片进行整理。要查看段的有关信息,可查看数据字典 dba_segments ,范围的信息可查看数据字典 dba_extents 。如果段的碎片过多, 将其数据压缩到一个范围的最简单方法便是用正确的存储参数将这个段重建,然后将旧表中的数据插入到新表,同时删除旧表。这个过程可以用 Import/Export (输入 / 输出)工具来完成。

---- Export ()命令有一个(压缩)标志,这个标志在读表时会引发 Export 确定该表所分配的物理空间量,它会向输出转储文件写入一个新的初始化存储参数 -- 等于全部所分配空间。若这个表关闭, 则使用 Import ()工具重新生成。这样,它的数据会放入一个新的、较大的初始段中。例如:

exp user/password file=exp.dmp compress=Y grants=Y indexes=Y

tables=(table1,table2);

---- 若输出成功,则从库中删除已输出的表,然后从输出转储文件中输入表:

imp user/password file=exp.dmp commit=Y buffer=64000 full=Y

---- 这种方法可用于整个数据库。

---- 以上简单分析了 Oracle 数据库碎片的产生、计算方法及整理,仅供参考。数据库的性能优化是一项技术含量高,同时又需要有足够耐心、认真细致的工作。 对数据库碎片的一点探讨
Renkey 2006-01-25
  • 打赏
  • 举报
回复
select tablespace_name,
count(blocks) num_exts,
max(blocks) max_exts,
sum(blocks) free_bolcks,
sum(bytes)/1048576 free_mbytes
from sys.dba_free_space
group by tablespace_name
用这个检查一下你的tablespace空间,及扩展次数
alter tablespace tablespace_name coalesce;
ragweed_wg 2006-01-25
  • 打赏
  • 举报
回复
在oracle管理工具中,将表空间调整回来试一下。
Torrice 2006-01-20
  • 打赏
  • 举报
回复
先EXP,然后Truncate,再IMP
本地没有空间,可以暂时使用映射网络硬盘周转一下。
bierbin 2006-01-20
  • 打赏
  • 举报
回复
如果是电力的数据,从量上肯定比这个要大。
bierbin 2006-01-19
  • 打赏
  • 举报
回复
我也遇到过类似问题,delete之后表占用的空间不会缩小,所以占用的空间逐渐上涨,没办法减下来。
xxiao07 2006-01-19
  • 打赏
  • 举报
回复
是银行啊,这个浙江个数据.
liuyi8903 2006-01-19
  • 打赏
  • 举报
回复
也可以导出你需要的数据后,进行重建.
或者truncate之后再导入.
sanoul 2006-01-19
  • 打赏
  • 举报
回复
好象也就银行\保险业才有这样的数据量啊
sanoul 2006-01-19
  • 打赏
  • 举报
回复
1:整理碎片
2:增加其他硬盘分区
cenlmmx 2006-01-19
  • 打赏
  • 举报
回复
注意index要rebuid
cenlmmx 2006-01-19
  • 打赏
  • 举报
回复
alter table move...移动到另一个表空间,再move回来
boydgmx 2006-01-19
  • 打赏
  • 举报
回复
根据你的实际情况,显然 MOVE 已经不能用了

只能先导出,然后 TRUNCATE 之后导入

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧