有關執行計劃,空間釋放的另一些

Joshua_q發表於2013-03-28

      最近負責起了DBA的部分工作,於是有一天在對錶空間的清理中發現了一張表,這個表有27G那麼大,是一個分割槽表,按天分割槽。我檢視了過程,每天刪除35天以前的資料,但是用的方法是delete,那麼我就可以很明確的推斷出,這個表佔用了大量本應該釋放的空間。

      我第一個使用的方法是move:

      

alter table table_name move partition part_1;

   這樣做很快,但是今天我在看一本書的時候,上面記載這種方法會更改rowid,會讓原來的索引失效。不過和我的有一點小出入:

       

      這個表上沒有索引,所以我這樣做了也無所謂,但是系統中存在著很多這樣的表,我需要試驗一下在分割槽表上move操作會不會導致索引失效。事實上我不需要建立索引實驗,我只需要知道move之後rowid變了沒有就好了。

      建一張分割槽表:

      

create table test1
(
   day_id varchar2(2),
   value number
)
partition by range(day_id)
(
   partition part_1 values less than ('02'),
   partition part_2 values less than ('03')
);
 
insert into test1 values ('01', 1);
insert into test1 values ('01', 2);
insert into test1 values ('02', 1);
insert into test1 values ('02', 2);
commit;

  

     上圖是資料。下面只查詢一下part_1裡的資料:

     

     然後在執行move語句,看看這樣之後的結果:

     

    仔細看,rowid確實變了,根據上面書中的記載,這樣是要導致索引失效的。後來經過實際測試,確實失效(我在day_id列上建立的local索引)。失效之後rebuild索引的時候不能使用這個語句:

    

alter index idx_name rebuild;

  而要一個分割槽一個分割槽的重建:

      

      繼續上面第一段的內容說,這個表被我從27G弄到了3.7G,省了快20G的空間出來,對我們這種沒什麼空間的系統很寶貴了。

      如果水位線高的話會嚴重影響查詢的執行計劃,test是一張不分割槽的表,這個表被我delete全部資料之後以append的方式插入了和delete之前相同多的資料。

      首先建立這個表:

      

create table test as select * from dba_objects;
--收集統計資訊
analyze table test compute statistics;

  執行計劃是這樣子的:

     

     然後將所有的資料刪除掉,以append方式插入原來的那麼多資料,然後分析表,然後看執行計劃:

     

delete from test;
commit;
insert /*+append*/ into test select * from dba_objects;
commit;
analyze table test compute statistics;

  

      如上如紅色框處所示,在查詢得到的結果相同的情況下,COST要大了很多,我推測這是掃描了那些本來應該釋放掉的資料塊所致。

      move之後情況就會變得不一樣:

      

      我聽說很多技術很正規的公司不允許寫select *。我覺得這個是對的,select你需要的欄位,就會大大降低很多壓力:

      

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28207565/viewspace-757314/,如需轉載,請註明出處,否則將追究法律責任。

相關文章