Oracle delete操做隱藏着你可能不知道的祕密

現象描述web

Deleteoracle數據庫中的經常使用操做,尤爲是在自動化測試中,初始化環境、前置準備都不可避免的進行增刪操做,但持續一時間後,可能會碰到表空間不足這類報錯現象,這就不由納悶兒了,明明插入數據前會有刪除的,數據總量並無呈現明顯的量級變化,爲何表佔用空間卻在偷偷增大呢?數據庫

 

現象分析oracle

出現上述現象的緣由是Delete操做並不會釋放佔用的空間。在講解緣由以前,先了解下oracle中高水位線的概念,有助於理解delete操做產生的這種現象。app

所謂的高水位(HWM),通俗的講就是一個標記,用來記錄已經有多少數據塊(Block)分配給表,能夠拿水庫的歷史最高水位來類比,當使用delete操做後,數據雖然被刪除了,但這個高水位的標記並無下降,就比如水庫的歷史最高水位不會由於水被釋放了而下降。於是,原則上在沒有外部干預的條件下,這個高水位標記值只會增大,不會下降。ide

 

實戰模擬重現現象測試

根據上面的現象描述和分析,接下來,我會用具體的實例模擬該現象,使你們能夠更直觀的瞭解。spa

1,建立一張測試表test,具體字段不須要關心,只要知道初始了存儲空間爲100M,如圖所示:3d

1.jpg 


2,建立完成後,咱們查看下數據表佔用的空間,如圖所示:orm

 2-記住三個關鍵數據.jpg


其中,查詢前須要對錶進行分析,使用命令爲:ANALYZE TABLE test ESTIMATE STATISTICS;查詢語句爲:SELECT blocks, empty_blocks, num_rows FROM user_tables WHERE table_name = 'TEST';blog

注意上面三個字段的結果:BLOCKS=0;  EMPTY_BLOCKS=13312;  NUM_ROWS=0,即當前表佔用的塊數爲0,默認1 BLOCK = 8kb,預分配的塊爲13312,行數爲0

一切都沒有問題,新建立的表,沒有數據嘛,固然行數爲0,佔用塊數爲0嘍。

 

3,寫一個語句塊,循環插入1000條語句,再次對test表進行分析、查詢,結果以下:

3插入數據.jpg


 

從圖中能夠看到,佔用BLOCKS=222NUM_ROWS=1000,合乎邏輯,插入了1000條數據,佔用了空間嘛。

 

4,使用Delete語句刪除1000條數據,再次對test表進行分析、查詢,結果倒是以下:

4刪除後行數爲0空間還佔用.jpg


從上圖中能夠清楚的看到,數據被刪除後,NUM_ROWS=0了,可是BLOCKS並無被置爲0,也就是這部分數據塊仍然被認爲是佔用的。

所以,就出現了本文一開始就提到的現象,隨着不斷的插入、刪除數據,BLOCKS也會不斷擴大,儘快delete操做後,可能表中數據量不多,但表佔用的存儲空間未減小。

 

解決方法

針對delete操做引發的空間不釋放現象,或者,更正式一點的說法,如何下降高水位線,方法有不少種,如,shrink spacemove tablespacecreate table xxx as select * from xxx 重建表等。使用這些方法前,咱們的原則是:

若是能夠truncate,直接truncate,該操做會重置高水位線,BLOCKS會被置爲0NUM_ROWS置爲0;不然,優先使用shrink space,該方法不須要重建索引。

接着上面第4步,咱們使用shrink space下降高水位線,釋放空間,其中,使用shrink space命令前,須要先alter table test enable row movement;開啓行移動,再次對錶進行分析、查詢,結果以下:

 5.jpg

 

從圖中能夠看出,此時BLOCKS已經被置爲0了,可是,細心的你可能也發現, EMPTY_BLOCKS已經不是初始的13312,而是此時的40,這說明shrink space不只會釋放高水位線如下的空間,也會釋放申請的空間,即高水位線上下都有操做,這也是與movetruncate的不一樣,它們只能釋放高水位線如下的空間。

 

shrink space經常使用操做命令

Shrink space的經常使用命令以下:

6 經常使用命令.jpg

 

Delete操做的潛在影響

根據上述分析,delete操做產生的潛在影響以下:

1. 全表掃描一般要讀出直到HWM標記的全部屬於該表的數據塊,即便該表中沒有任何數據;(形成查詢變慢)

2. 插入操做時使用append關鍵字,即便HWM如下有空閒的數據庫塊,插入時使用HWM以上的數據塊;(形成HWM自動增大)

 

總結

經過上文的現象描述和分析,隨着insert的不斷操做,高水位線也隨着不斷增長,儘管delete了數據,但高水位線並無降低,致使表佔用的空間沒有釋放。所以,在實際應用中,若是可能,儘可能使用truncate,並且該操做高效、快速;不然要考慮下delete操做遺留的影響,使用合適的方法整理空間。

相關文章
相關標籤/搜索