Oracle中應(yīng)用Export的一個(gè)問題
2024-08-29 13:39:35
供稿:網(wǎng)友
系統(tǒng)環(huán)境
硬件:
方正圓明服務(wù)器
768M的內(nèi)存
硬盤有二個(gè)分區(qū)C、D,光驅(qū)為E
軟件:
操作系統(tǒng)windows 2000 SERVER
數(shù)據(jù)庫Oracle 8.0.6 for NT
數(shù)據(jù)庫:
創(chuàng)建數(shù)據(jù)庫后,手工創(chuàng)建了二個(gè)表空間,在存儲治理器中查看其屬性如下:
TS_PAY 1200M (initial size 80k, next size 80k, increase size 50%)
TS_IDX 1200M (initial size 80k, next size 80k, increase size 50%)
操作
運(yùn)行創(chuàng)建數(shù)據(jù)表、索引、觸發(fā)器及其視圖的腳本后,TS_PAY占用416M,TS_IDX占用130M。
分三次錄入相應(yīng)的數(shù)據(jù),其中建立在表空間TS_PAY的數(shù)據(jù)表的數(shù)據(jù)量為16M, 建立在表空間TS_IDX的數(shù)據(jù)表的數(shù)據(jù)量為12M。
每次錄入數(shù)據(jù)后,用Oracle8.0.6的實(shí)用工具EXPort以用戶模式導(dǎo)出整個(gè)數(shù)據(jù),其他參數(shù)為默認(rèn)值(導(dǎo)出的文件大小為9.46M)。其中在中途用Oracle8.0.6的實(shí)用工具Import作過幾次數(shù)據(jù)導(dǎo)入。
現(xiàn)象
在OEM的存儲治理中查看表空間的使用情況,發(fā)現(xiàn)TS_PAY占用856M,TS_IDX占用423M。對幾個(gè)占用空間圈較大的表和索引作了查詢,發(fā)現(xiàn)其數(shù)據(jù)的記錄數(shù)據(jù)為0,但其占用空間由初建時(shí)的20M變?yōu)?0M。
錄入的記錄數(shù)只有十幾條,而且每條記錄的占用空間也不大,所以表空間的這種占用速度與表的數(shù)據(jù)量增長呈現(xiàn)出的比例是極度不正常的。
原因分析
經(jīng)過實(shí)際測試發(fā)現(xiàn),上述現(xiàn)象的產(chǎn)生是由于在導(dǎo)出時(shí)使用了參數(shù)COMPRESS = Y。
在實(shí)用工具Export中,參數(shù)Compress的缺省值為Y。參數(shù)Compress指定Export和Import如何治理表數(shù)據(jù)的初始區(qū)。
假如缺省的COMPRESS = Y,則Export對表數(shù)據(jù)加標(biāo)記,以便在導(dǎo)入時(shí)合并到某個(gè)初始區(qū)。也就是說,參數(shù)COMPRESS = Y告訴ORACLE合計(jì)一個(gè)表中所有已分配的空間,并且為了反映當(dāng)前總的已分配空間,在導(dǎo)出轉(zhuǎn)儲文件中修改了表創(chuàng)建語句的初始值。初始區(qū)值是導(dǎo)出執(zhí)行前表中所有已分配空間的總和。
我們假設(shè)某個(gè)表有6 個(gè)分區(qū),你想壓縮它。五個(gè)分區(qū)中的每一個(gè)都分配了512000(PCTINCREASE=0)。在每個(gè)分區(qū)中只有204800個(gè)字節(jié)是有數(shù)據(jù)的,并且在最后一個(gè)區(qū)中沒有已用的字節(jié)即空閑512000字節(jié)。當(dāng)使用參數(shù)COMPRESS=Y時(shí),ORACLE簡單地累加了所有已分配的空間,然后分配3072000字節(jié)作為導(dǎo)出轉(zhuǎn)儲文件中CREATE TABLE語句的初始區(qū)值。這樣當(dāng)你執(zhí)行操作后,ORACLE將把數(shù)據(jù)放在表區(qū)最初的大約1024000字節(jié)中,將近2048000個(gè)字節(jié)的空間是空閑的。
假如指定COMPRESS = N,Export將使用當(dāng)前存儲參數(shù),包括初始區(qū)和下一個(gè)區(qū)的大小值。參數(shù)值可能是在CREATE TABLE或ALTER TABLE語句中指定的值,也可能是數(shù)據(jù)庫系修改過的值。例如,假如表增大而且假如PCTINCREASE參數(shù)不為零,NEXT區(qū)的大小值就可能被修改。
雖然實(shí)際的合并是在導(dǎo)入時(shí)執(zhí)行的,但是只能在導(dǎo)出時(shí),而不能在導(dǎo)入時(shí)指定COMPRESS參數(shù)。是Export實(shí)用程序,而不是Import實(shí)用程序生成數(shù)據(jù)定義,包括存儲參數(shù)定義。這樣,假如在導(dǎo)出時(shí)指定COMPRESS = Y,就只能以合并形式導(dǎo)入數(shù)據(jù)。COMPRESS參數(shù)不壓縮LOB數(shù)據(jù),對于LOB數(shù)據(jù),使用初始區(qū)大小和下一區(qū)大小的原始值。
解決辦法
1、沒有進(jìn)行過導(dǎo)出導(dǎo)入操作或沒有做過導(dǎo)入?yún)?shù)為COMPRESS=Y的數(shù)據(jù)。
這時(shí)只需在導(dǎo)出數(shù)據(jù)時(shí),選擇參數(shù)COMPRESS的值為N,就不會出現(xiàn)上述現(xiàn)象。
2、假如數(shù)據(jù)已經(jīng)以COMPRESS = Y方式導(dǎo)出,而且又被Import實(shí)用工具導(dǎo)入或數(shù)據(jù)庫中的數(shù)據(jù)損壞,只有用導(dǎo)出的數(shù)據(jù)導(dǎo)入。
這種情況的處理較為復(fù)雜一點(diǎn),可以分為以下幾個(gè)步驟來做。
(1)對于幾個(gè)占用空間較大的數(shù)據(jù)表分別創(chuàng)建中間臨時(shí)表,例如,對于表SBYY我們可以進(jìn)行如下操作:
CREATE TABLE T_TMP AS SELECT * FROM SBYY;
(2)刪除數(shù)據(jù)庫中的表SBYY:
DROP TABLE SBYY;
(3)在數(shù)據(jù)庫中按原結(jié)構(gòu)重建表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)將臨時(shí)表T_TMP中的數(shù)據(jù)插入到重建的表SBYY中:
INSERT INTO SBYY SELECT * FROM T_TMP;
(5)刪除臨時(shí)表T_TMP。
DROP TABLE T_TMP;
對于其它數(shù)據(jù)量不大,但占空間較大的表或索引依次進(jìn)行如上五個(gè)步驟的處理即可。
注重,這種方法對于表間關(guān)系不復(fù)雜的數(shù)據(jù)清理比較簡便而有用,對于關(guān)聯(lián)較復(fù)雜的表及其索引等,要進(jìn)行仔細(xì)分析表間關(guān)系才可動手。