巧妙使用exchange partition的一個案例
前幾天寫過一篇文章討論過分割槽表的線上重定義,其實就是另外一個分割槽表和現有的分割槽表做資料字典資訊的交換
http://blog.itpub.net/23718752/viewspace-1734195/
當然了除此之外還是需要一些相應的許可權,在這個過程中會在內部做類似物化檢視一樣的資料重新整理,保持資料表的可訪問性。
在不同的場景中還是會有不同的取捨,比如現在的場景,情況發生了一些變化,分割槽存在問題,要重新分割槽是肯定的,除此之外,開發希望把一些舊資料做一些清理,比如根據時間來分割槽,可能對於開發來說,最近一段時間的資料保留就可以了,之前很舊的資料就只是需要做一個備份,直接清掉,基本評估下來,可能90%以上的資料都需要做清理。
所以這個時候還是使用線上重定義就有一些弊端了。
首先是時間的問題,線上重定義的過程中,其實內部還是在做資料的複製工作。相當於把資料從一個源流動到另外一個源。內部是這樣的資料重新整理,對外保持始終可以訪問,所以對於上億條記錄來說這個時間就比較長了。
其次就是效率問題,因為重新分割槽後,可能大部分資料都不需要了,這個時候做線上重定義還會做資料複製,然後在一定的時間之後還是需要再次做資料清理。這個時候相當於做了重複工作。效率會大大折扣。
這個時候根據目前的問題情況,考慮透過以下的方式來實現。
首先是資料內部的複製,為了減少這種開銷,可以考慮把分割槽表的預設分割槽和一個普通表做交換,這個過程是一個資料字典級的變更,所以速度還是很快的。
然後可以交換後的分割槽做split partition的操作。這個時候split操作時間會持續極短。影響相對來說很小。
然後就是資料的清理,這個時候清理工作就會變為一種選擇性的資料匯入,因為需要匯入的資料量還是很小的。所以只需要把需要時間範圍內的資料匯入即可。
我們來簡單試一試。
還是之前所用的分割槽表,現在只有一個預設分割槽。
CREATE TABLE tab_part
(
col1 varchar2(30),
col2 DATE
)
partition BY range(col2)
(
partition tab_part_maxvalue values less than (maxvalue)
);
我們希望達到的效果是下面的分割槽形式。
CREATE TABLE tab_part
(
col1 varchar2(30),
col2 DATE
)
partition BY range(col2)
(
partition tab_part_2014 VALUES less than (to_date('2014-08-01','yyyy-mm-dd')),
partition tab_part_2015 VALUES less than (to_date('2015-08-01','yyyy-mm-dd')),
partition tab_part_maxvalue values less than (maxvalue)
);
然後給分割槽表建立分割槽索引,然後我們簡單插入幾條資料。
create index inx_tab_part on tab_part(col1) local;
INSERT INTO tab_part VALUES(1,SYSDATE-400);
INSERT INTO tab_part VALUES(11,SYSDATE-600);
commit;
資料情況如下:
COL1 COL2
------------------------------ ---------
1 09-APR-15
11 05-MAR-14
這個時候我們建立一個表test_tab01來做為中間過渡的一個表。
CREATE TABLE TEST_TAB01(
col1 varchar2(30),
col2 DATE);
這個時候就開始使用exchange partition來把分割槽的資料做個交換。
ALTER TABLE tab_part EXCHANGE PARTITION tab_part_maxvalue
WITH TABLE TEST_TAB01 ;
交換的速度很快,來看看操作之後的資料情況,可以看到資料都到了test_tab01裡面。
SQL> select count(*)from tab_part;
COUNT(*)
----------
0
SQL> select count(*)from test_tab01;
COUNT(*)
----------
2
這個時候分割槽還是沒變,但是資料給交換出來了。
SQL> select table_name,partition_name from user_tab_partitions where table_name='TAB_PART';
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
TAB_PART TAB_PART_MAXVALUE
我們接下來要做split partition的工作。
SQL> alter table tab_part SPLIT PARTITION tab_part_maxvalue at (to_date('2014-08-01','yyyy-mm-dd')) INTO ( PARTITION tab_part_2014 , PARTITION tab_part_maxvalue);
Table altered.
SQL> alter table tab_part SPLIT PARTITION tab_part_maxvalue at (to_date('2015-08-01','yyyy-mm-dd')) INTO ( PARTITION tab_part_2015 , PARTITION tab_part_maxvalue);
Table altered.
這個時候再來看分割槽的情況,就達到了我們預期的要求。
SQL> select table_name,partition_name from user_tab_partitions where table_name='TAB_PART';
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
TAB_PART TAB_PART_2014
TAB_PART TAB_PART_2015
TAB_PART TAB_PART_MAXVALUE
如果對exchange partition還是有一定的疑慮,想索引會不會受到影響,如果是本地索引是沒有問題的,如果是global全域性索引,就需要rebuild
SQL> select index_name,partition_name,status from user_ind_partitions where index_name='INX_TAB_PART';
INDEX_NAME PARTITION_NAME STATUS
------------------------------ ------------------------------ --------
INX_TAB_PART TAB_PART_2014 USABLE
INX_TAB_PART TAB_PART_2015 USABLE
INX_TAB_PART TAB_PART_MAXVALUE USABLE
這個時候重新分割槽完成了,要做的事情就是匯入資料了,選擇性的匯入資料,根據時間戳即可。
當然了好幾億條記錄,不建個索引根本說不過去。
create index inx_test_tab01 on test_tab01(col);
我們就可以使用insert的方式匯入資料即可。
insert into tab_part select *from test_tab01 where col>sysdate-10;
最後為了把exchange partiton的一個精髓突出出來和線上重定義區分開了,可以做一個很簡單的小例子。
我們還是建立原來的表tab_part
CREATE TABLE tab_part
(
col1 varchar2(30),
col2 DATE
)
partition BY range(col2)
(
partition tab_part_maxvalue values less than (maxvalue)
);
create index inx_tab_part on tab_part(col1) local;
我們接著建立一個表test_tab01,這個時候唯一的不同之處就是欄位名不同,但是資料型別相同。
CREATE TABLE TEST_TAB01(
a varchar2(30),
b DATE);
然後嘗試去做exchange partition的時候是沒有問題的。
ALTER TABLE tab_part EXCHANGE PARTITION tab_part_maxvalue
WITH TABLE TEST_TAB01 ;
我們看看交換分割槽之後的表結構變化情況
SQL> desc tab_part
Name Null? Type
----------------------------------------- -------- ----------------------------
COL1 VARCHAR2(30)
COL2 DATE
SQL> desc test_tab01
Name Null? Type
----------------------------------------- -------- ----------------------------
A VARCHAR2(30)
B DATE
可以看到欄位名沒有任何變化,還是原來的欄位名,但是在內部做了資料字典資訊的交換,把相應的段資訊做了交換而已。這也就exchange partition的主要思想。
透過這個案例可以看到,exchange partition還是大有可為,而且在很多場景下可以達到很滿意的效果,線上重定義也不錯,不過在選擇的時候還是需要綜合評定,沒有最好的方法,最有最適合的方法。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-1738539/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Redux中介軟體對閉包的一個巧妙使用Redux
- 一種巧妙的使用 CSS 製作波浪效果的思路CSS
- Vue一個案例引發的遞迴元件的使用Vue遞迴元件
- Vue一個案例引發「動畫」的使用總結Vue動畫
- MySQL:一個奇怪的hang案例MySql
- 巧妙的CSSCSS
- 使用View modification擴充套件SAP Fiori應用的一個案例View套件
- eventBus(封裝) 一個巧妙的解決vue同級元件通訊的思路封裝Vue元件
- 「複製帶隨機指標的連結串列」的一個很巧妙解法隨機指標
- Partition Pruning和Partition-Wise Joins
- 一種巧妙的drawable.xml替代方案XML
- 如何巧妙的使用 Mac 上自帶的提醒事項?Mac
- Bootstrap一個小案例boot
- 【MySQL】NOT EXISTS優化的一個案例MySql優化
- 求一個ot的專案例項
- 一個簡單的MVP模式案例MVP模式
- 乾貨|一個案例學會Spring Security 中使用 JWTSpringJWT
- 巧妙的煎餅
- PostgreSQL 從熊燦燦一個獲取固定字元的SQL 分析巧妙之處SQL字元
- Clique Partition
- 通過MOVE PARTITION來回收已經使用的空間
- 在微服務架構中使用token exchange主要的優勢微服務架構
- oracle partition by group by,詳解partition by和group by對比Oracle
- 一個具有啟示性的最新 NFT 案例
- 分割槽Partition
- MySQL:Innodb 一個死鎖案例MySql
- 通過一個案例理解 JWTJWT
- JDK中Lambda表示式的序列化與SerializedLambda的巧妙使用JDKZed
- 今天測試了一下update partition table的part key
- iOS開發UI篇--使用UICollectionView實現一個列表頭部拉伸效果的案例iOSUIView
- 巧妙使用免費OA管理企業資料
- Exchange 2016部署實施案例篇-05.OOS部署與基礎配置
- Vue-loader 的巧妙玩法Vue
- 巧妙設定job的interval
- ZDI研究人員披露四個Microsoft Exchange中的0day漏洞ROS
- 一個簡單案例的Vue2.0原始碼Vue原始碼
- 巧妙讓兩個span元素中間的空格不再有間隙
- Kubernetes中分散式儲存Rook-Ceph的使用:一個ASP.NET Core MVC的案例分散式ASP.NETMVC
- Exchange Online Mailbox RestorationAIREST