系统环境
硬件:
方正圆明服务器
768M的内存
硬盘有二个分区C、D,光驱为E
软件:
操作系统windows 2000 SERVER
数据库Oracle 8.0.6 for NT
数据库:
创建数据库后,手工创建了二个表空间,在存储治理器中查看其属性如下:
TS_PAY 1200M (initial size 80k, next size 80k, increase size 50%)
TS_IDX 1200M (initial size 80k, next size 80k, increase size 50%)
操作
运行创建数据表、索引、触发器及其视图的脚本后,TS_PAY占用416M,TS_IDX占用130M。
分三次录入相应的数据,其中建立在表空间TS_PAY的数据表的数据量为16M, 建立在表空间TS_IDX的数据表的数据量为12M。
每次录入数据后,用Oracle8.0.6的实用工具EXPort以用户模式导出整个数据,其他参数为默认值(导出的文件大小为9.46M)。其中在中途用Oracle8.0.6的实用工具Import作过几次数据导入。
现象
在OEM的存储治理中查看表空间的使用情况,发现TS_PAY占用856M,TS_IDX占用423M。对几个占用空间圈较大的表和索引作了查询,发现其数据的记录数据为0,但其占用空间由初建时的20M变为50M。
录入的记录数只有十几条,而且每条记录的占用空间也不大,所以表空间的这种占用速度与表的数据量增长呈现出的比例是极度不正常的。
原因分析
经过实际测试发现,上述现象的产生是由于在导出时使用了参数COMPRESS = Y。
在实用工具Export中,参数Compress的缺省值为Y。参数Compress指定Export和Import如何治理表数据的初始区。
假如缺省的COMPRESS = Y,则Export对表数据加标记,以便在导入时合并到某个初始区。也就是说,参数COMPRESS = Y告诉ORACLE合计一个表中所有已分配的空间,并且为了反映当前总的已分配空间,在导出转储文件中修改了表创建语句的初始值。初始区值是导出执行前表中所有已分配空间的总和。
我们假设某个表有6 个分区,你想压缩它。五个分区中的每一个都分配了512000(PCTINCREASE=0)。在每个分区中只有204800个字节是有数据的,并且在最后一个区中没有已用的字节即空闲512000字节。当使用参数COMPRESS=Y时,ORACLE简单地累加了所有已分配的空间,然后分配3072000字节作为导出转储文件中CREATE TABLE语句的初始区值。这样当你执行操作后,ORACLE将把数据放在表区最初的大约1024000字节中,将近2048000个字节的空间是空闲的。
假如指定COMPRESS = N,Export将使用当前存储参数,包括初始区和下一个区的大小值。参数值可能是在CREATE TABLE或ALTER TABLE语句中指定的值,也可能是数据库系修改过的值。例如,假如表增大而且假如PCTINCREASE参数不为零,NEXT区的大小值就可能被修改。
虽然实际的合并是在导入时执行的,但是只能在导出时,而不能在导入时指定COMPRESS参数。是Export实用程序,而不是Import实用程序生成数据定义,包括存储参数定义。这样,假如在导出时指定COMPRESS = Y,就只能以合并形式导入数据。COMPRESS参数不压缩LOB数据,对于LOB数据,使用初始区大小和下一区大小的原始值。
解决办法
1、没有进行过导出导入操作或没有做过导入参数为COMPRESS=Y的数据。
这时只需在导出数据时,选择参数COMPRESS的值为N,就不会出现上述现象。
2、假如数据已经以COMPRESS = Y方式导出,而且又被Import实用工具导入或数据库中的数据损坏,只有用导出的数据导入。
这种情况的处理较为复杂一点,可以分为以下几个步骤来做。
(1)对于几个占用空间较大的数据表分别创建中间临时表,例如,对于表SBYY我们可以进行如下操作:
CREATE TABLE T_TMP AS SELECT * FROM SBYY;
(2)删除数据库中的表SBYY:
DROP TABLE SBYY;
(3)在数据库中按原结构重建表SBYY:
CREATE TABLE SBYY(
JLDW_DMchar(4)NOT NULL,
JLDW_MCvarchar2(20) NOT NULL,
JLDW_JCvarchar2(10) NOT NULL,
XYBZ char(1)NOT NULL,
CONSTRAINT PK_SB_DM_JLDW_CKHW PRIMARY KEY (JLDW_DM)
);
(4)将临时表T_TMP中的数据插入到重建的表SBYY中:
INSERT INTO SBYY SELECT * FROM T_TMP;
(5)删除临时表T_TMP。
DROP TABLE T_TMP;
对于其它数据量不大,但占空间较大的表或索引依次进行如上五个步骤的处理即可。
注重,这种方法对于表间关系不复杂的数据清理比较简便而有用,对于关联较复杂的表及其索引等,要进行仔细分析表间关系才可动手。