創建表測試
(id int,
文本clob
);
SQL & gtselect * from user _ segments
段名稱分區名稱段類型表空間名稱
字節塊擴展區INITIAL _ EXTENT NEXT _ EXTENT MIN _ EXTENTS MAX _ EXTENTS PCT _ INCREASE FREELIST FREELIST _ GROUPS BUFFER _ POOL
- - - -
- - - - - - - - - - - -
測試表用戶
41943040 5120 55 65536 1 2147483645默認
SYS _ il 0000049476 c 00002 $ $ lob index用戶
65536 8 1 65536 1 2147483645默認
SYS _ lob 0000049476 c 00002 $ $ lob segment用戶
65536 8 1 65536 1 2147483645默認
alter index SYS _ il 0000049476 c 00002 $ $重建表空間用戶在線無日誌記錄
ORA-02327:無法使用數據類型LOB的表達式創建索引。
我們先回憶壹下相關知識。以下來自Oracle 9i &;10G編程藝術
Lobindex和lobsegment,它們是做什麽的?創建這些細分市場是為了支持我們的LOB專欄。我們實際的lob數據存儲在LOBsegment中(實際上,LOB數據也可能存儲在table T中,但我們將在後面討論。
這將在啟用row子句中的存儲時更詳細地解釋)。LOBindex用於執行lob的導航,以找到它的某些部分。創建LOB列時,壹般來說,這是壹個指針(
指針),或LOB定位器。我們的應用程序獲得的是這個LOB定位器。當請求LOB的“12.000 ~ 2000字節”時,LOB locator將用於lobindex找出這些字節。
存儲它的位置,然後訪問lobsegment。使用lobindex可以很容易地找到LOB的各個部分。從這個角度來看,LOB可以被認為是壹種主/從關系。
表中的lob實際上只指向lobindex,而lob index又指向lob本身的各個部分。為了獲得LOB中的N~M字節,應該對表中的指針(LOB定位器)進行解引用,並遍歷lobindex結構以找到所需的內容。
數據庫(chunk),然後按順序訪問。這使得隨機訪問LOB的任何部分都同樣快,妳可以以同樣的速度獲得LOB的第壹、中間或最後部分,因為不需要從頭遍歷LOB。
ORACLE還表示:lob索引是壹種與lob存儲緊密相關的內部結構。也就是說不允許直接重建。
但我認為可以明確的是,INDEX是用來確定LOBSEGMENT的位置的。如果經常對表中的行進行DML或者對大字段進行DML,我覺得重構還是有必要的。
既然是指數,就要遵守指數化的原則。大量的DML必然會使索引頁節點越來越深,但它包含了自由空間。
ORACLE METALINK建議使用alter table...將重建索引的move命令,即使用ALTER TABLE MOVE語句來索引重建。
讓我們來測試壹下:
要理解實驗結果,我們必須先理解幾個概念:
1,在ROW中默認的子句是(在行中啟用存儲),即小於4000字節就存儲在表段中,大於4000字節就存儲在lob段中。同時,LOBINDEX用於指定位置。
使用DISABLE STORAGE IN ROW,即無論它有多大,它都存在於LOBSEGMENT中。
2.CHUNK代表最小LOGSEGMENT的存儲單元,壹個CHUNK只用於壹個段線。如果壹個CHUNK設置為32K,而妳的段線只有2K,那就浪費了30k。
3.緩存指示是否將讀取記錄到緩存中的日誌段中。默認值為NOCACHE,可以是緩存和緩存讀取。前者既省讀又省寫,後者省讀,寫的是直寫。而NOCACHE的意思是直接讀寫。
下面是我建表的語句。
創建表“PPTEST”。"測試2 "
(“ID”號(*,0),
" TXT" CLOB
)pct free 10 PCTUSED 40 init trans 1 MAXTRANS 255 no壓縮日誌記錄
存儲(初始65536下壹個1048576最大擴展1最大擴展2147483645
PCTINCREASE 0空閑列表1空閑列表組1 BUFFER_POOL默認值)
表空間“用戶”
LOB(“TXT”)存儲為(
表空間“用戶”禁用行塊中的存儲8192百分比版本10
諾卡奇
存儲(初始65536下壹個1048576最大擴展1最大擴展2147483645
PCTINCREASE 0空閑列表1空閑列表組1 BUFFER_POOL默認值))
我在行塊8192中禁用了存儲,該塊是8K。
現在我插入數據。
SQL & gt插入測試2
2 select * from test
插入589824行
這裏有58W多線。計算線段占用的空間。589824*8K=4.5G
看看這個:
select SEGMENT_NAME,SEGMENT_TYPE,BYTES/1024/1024/1024 GB,BLOCKS from user _ segments
SYS _ il 0000049480 c 00002 $ $ lob index 0.0302733968
SYS _ lob 0000049480 c 00002 $ $ lob segment 4.54199218 595328
測試2表0.01855468 2432
事實上,我們的LOGSEGMENT是4.5G
現在我們收集統計信息,並對指數進行如下分析:
SQL & gt執行DBMS _ stats . gather _ schema _ stats(own name = & gt;' PPTEST ',cascade = & gt真);
PL/SQL過程已成功完成
分析索引SYS _ il 0000049480 c 00002 $ $ validate結構;
分析索引SYS _ il 0000049480 c 00002 $ $ compute statistics;
不知道為什麽查了壹下沒有找到LOGINDEX的結構信息。
但考慮到大量的DML就足夠了,再築指數的規模肯定會減小。
現在我們來做重新折疊實驗。
首先,模擬大量刪除的插入,
刪除test2
插入測試2
select id,txt from (select rownum rn,id,txt from test)其中mod(rn,8)= 0;
先全部刪除,再插入1/8的數據。(過程極其緩慢)
SQL & gt刪除test2
刪除了589824行
考試
select SEGMENT_NAME,SEGMENT_TYPE,BYTES/1024/1024/1024 GB,BLOCKS from user _ segments
SYS _ il 0000049480 c 00002 $ $ lob index 0.078125 10240
SYS _ lob 0000049480 c 00002 $ $ lob segment 4.6049218 603520
測試2表0.01855468 2432
索引塊的數量大大增加,占用的空間也大大增加。我不太明白為什麽這裏增加了很多。這個時候其實是沒有數據的。
然後就插入了。
SQL & gt插入測試2
2 select id,txt from (select rownum rn,id,txt from test)其中mod(rn,8)= 0;
插入73728行
考試
select SEGMENT_NAME,SEGMENT_TYPE,BYTES/1024/1024/1024 GB,BLOCKS from user _ segments
SYS _ il 0000049480 c 00002 $ $ lob index 0.0859375 11264
SYS _ lob 0000049480 c 00002 $ $ lob segment 5.65449218 669056
測試2表0.01855468 2432
其實這個時候數據只有1/8,但是LOGSEGMENT和LOBINDEX更大。所以浪費了很多空間。
我們直接重建TEST2表。
SQL & gtalter table test2移動表空間用戶;
考試
SYS _ il 0000049480 c 00002 $ $ lob index 0.0859375 11264
SYS _ lob 0000049480 c 00002 $ $ lob segment 5.65449218 669056
測試2表0.00292968 384
剛剛重建了測試2部分。
使用語句
更改表test2移動
表空間用戶
LOB (TXT)存儲為lobsegment
(表空間用戶);
進行重建
重建期間可以看到的臨時物體如下:
4.635臨時0.00061035 80
4.187臨時0.1328125 17408
4.611臨時0.00097656 128
顯然,表本身、LOBSEGMENT和LOBINDEX都是重新構建的。
然後檢查
SQL & gtselect SEGMENT_NAME,SEGMENT_TYPE,BYTES/1024/1024/1024 GB,BLOCKS from user _ segments
分段名稱分段類型GB數據塊
- - - -
測試2表0.00292968 384
LOBSEGMENT
SYS _ il 0000049480 c 00002 $ $ lob index 0.00390625 512
因為我這裏用的是LOBSEGMENT,所以之前的SYS_LOB0000049480C00002$$ $已經改成了lobsegment,可以看出此時容量正常。0.56G只是之前的1/8。
如果要單獨重建,會報錯。METALINK上的記錄如下:
說明
-
' ALTER TABLE foo MODIFY LOB (lobcol)...語法不允許
對於表空間的更改
更改表my_lob
修改LOB (a_lob)
(表空間new _ tbsp);
(表空間new_tbsp)
*
ORA-22853:無效的LOB存儲選項規範
您必須使用MOVE關鍵字,如示例所示。
結論:
1和LOGSEGMENT不會重用HWM以下的空間,所以大量的DML會不斷增加其大小。
2.需要重建LOBsegment和LOBINDEX。語法如下:
更改表test2移動
表空間用戶
LOB (TXT)存儲為lobsegment
(表空間用戶);
必須和表壹起重建,沒有辦法單獨重建LOBSEGMENT或LOGINDEX。