Oracle大表分區(表大小超過2G)

背景:公司要求將數據庫中表超過2G的表進行分區。剛好我們負責的表有5張大於2G的。所以需要進行表分區。

所謂分區,講的的通俗點,就是根據某個字段的範圍進行劃分,將表分成幾塊。以後查詢,維護都更加方便。

  比如可以根據創建時間,2018年的數據放入一個分區,以後每3年存入一個分區。

實際環境:我負責的這個表,大小是12G作右,接近7千萬條數據。

因爲這個表已經使用了很多年了,剛開始建表的時候沒有考慮到數據會變的這麼大。所以沒有建分區。現在的思路是重新建立一張分區表和源表一模一樣,不同的是該表進行了分區。然後把7千萬條數據導入到該表。最後將兩個表互換名字。

難點:難點有幾個:1.導入數據,7千萬的數據不能簡單的insert...select。因爲它是自動commit。可能最後commit時服務器都撐爆了。                       2.換名字。兩個表互換名字,如果將新表插入了數據,此時源表還在進行數據的增刪改怎麼辦,這樣數據就沒有同步了。

                              3.索引的問題,建表的時候不要建索引,數據插入完後再建索引。不然插入數據時效率較低。

 

實際操作:由於公司的保密,語句不能copy出來。

  第一:根據源表創建分區表,根據創建時間字段,18年以前的數據爲一分區,後面每年一分區。

  create table A_temp as select * from A where 1=0 partition by RANGE(create_time) 

INTERVAL (numtoyminterval(1,'year'))
(partition part_t01 values less than(to_date('2018-01-01', 'yyyy-mm-dd')));

第二:表註釋和字段註釋以及默認值和不爲空的設置,付權限,同義詞。

    comment on table A_temp is 'XXX';

    comment on column A.xxx is 'ccc';......

第三:插入數據,採用並行插入,提供效率。儘量在用戶使用量小的時候做表分區。比如我們在晚上11:30部署,基本沒有用戶做增刪改操作。並且設置源表爲只讀。

  alter table A read only;

 

//分批插入

declare

     vd_start_date date;

     vd_end_date date;

begin

    vd_start_date:=to_date('20090301','YYYYMMDD'),

   vd_end_date:=to_date('20191130','YYYYMMDD');

while vd_start_date<=vd_end_date

 loop 

   insert /* append parallel(A,4) */ into A_temp  A

   select /* append parallel(T,4) */ from A 

   where created_date>=vd_start_date and 

   created_date<add_month(v_start_date,3);

commit;

vd_start_date:=add_month(vd_start_date,3);

end loop;

end;

/;

第五:建索引,約束。數據插入完後再建索引和約束。效率比較高

   create index xxx on A_temp(xxx);...

第六:建同義詞。

   create public synonym for A_temp;

第七:解除原表只讀。

 alter table A read write;

第八:給新表賦權限:

  grant select on A_temp to XXX;

第九:表名交換。

 alter table A rename to A_new;

alter table A_temp rename to A;

這樣,就重新建了一張表A_temp.和表A一樣,並且是已經分區了的。從而替代了A.

最後可以刪除A_new.

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章