1. 程式人生 > >全面總結Oracle中的分割槽表(精)

全面總結Oracle中的分割槽表(精)

何時使用分割槽表

分割槽表是對錶按照規則進行劃分,這個是要根據業務場景來確定的。

建議值

1 大於2G的表
2 分割槽鍵必須反應業務需求,CUDR儘量不要跨分割槽操作
如果通過有效隔離,全表掃描就變成了分割槽掃描,降低IO,但如果已經使用索引,且結果集較小時,做分割槽不一定會提高效率,這點要注意。

分割槽表設計思路

分割槽的資料要儘量保持均勻,偏差控制在20%左右。分割槽鍵的選擇不應經常被UPDATE,要避免NULL值出現,否則會被拋到MAXVALUE分割槽,還要注意鍵值大小寫分割槽的問題。分割槽不宜過多,hash分割槽必須是2的n次方倍,也要考慮CPU的併發能力。

分割槽表型別

範圍分割槽(Range Partition)

通常是使用頻率最高的分割槽,如按月份劃分,這樣的資料保持均勻性比較好,如果劃分的均勻性不是很好,需要考慮其他分割槽方法。

CREATE TABLE Test(
	ID NUMBER,
	CDATE VARCHAR2(8)
)

PARTITION BY RANGE(CDATE)(
	PARTITION par_test_2017_q1 VALUES LESS THAN ('20170401'),
	PARTITION par_test_2017_q2 VALUES LESS THAN ('20170701'),
	PARTITION par_test_2017_q3 VALUES LESS THAN ('201701001'),
	PARTITION par_test_2017_q3 VALUES LESS THAN ('20180101'),
	PARTITION par_test_2018 VALUES LESS THAN (maxvalue),
)ENABLE ROW MOVEMENT;
--ENABLE ROW MOVEMENT要加,因為分割槽鍵如果需要UPDATE操作的話,會對其進行重新分割槽,有可能分到別的去了。

雜湊分割槽(Hash Partition)

如果資料不是那麼容易進行劃分,通過這種方式就很靈活了。可以將資料均勻的插入到不同的塊,在併發時有利於提高效率,當無法用Range分割槽時,就可以用Hash分割槽。

CREATE TABLE Test(
	ID NUMBER,
	CDATE VARCHAR2(8)
)
PARTITION BY HASH(NAME)(
	PARTITION par_test_01,
	PARTITION par_test_02,
	PARTITION par_test_03,
	PARTITION par_test_04
);

列表分割槽(List Partition)

當需要明確控制如何將資料進行分割槽時,採用這種方式。只能進行單列分割槽,可以講資料進行分組,比如按城市分割槽,幾個城市放一起。

CREATE TABLE Test(
	ID NUMBER,
	CITY VARCHAR2(8)
)
PARTITION BY LIST(CITY) (
	PARTITION par_test_01 VALUES('BJ','BD'),
	PARTITION par_test_02 VALUES('XA','SJZ'),
	PARTITION par_test_03 VALUES('SH','HZ'),
	PARTITION par_test_01 VALUES('SZ','GZ')
)ENABLE ROW MOVEMENT;

複合分割槽

側重於資料歸檔了,將上述三個組合起來用。根據業務需求的資料分佈來了選擇合適的組合。
語法

PARTITION BY RANGE(CDATE) SUBPARTITION BY HASH(NAME)(
	PARTITION par_test_2017_q1 VALUES LESS THAN ('20170401')(
		SUBPARTITION sp_test_2017_q1_01,
		SUBPARTITION sp_test_2017_q1_02,
		SUBPARTITION sp_test_2017_q1_03,
		SUBPARTITION sp_test_2017_q1_04),
	PARTITION par_test_2017_q1 VALUES LESS THAN (maxvalue)(
		SUBPARTITION sp_test_2017_max_01,
		SUBPARTITION sp_test_2017_max_02,
		SUBPARTITION sp_test_2017_max_03,
		SUBPARTITION sp_test_2017_max_04),
)

除了以上三種分割槽,Oracle還提供了4個分割槽方式,來針對不同的使用場景。我感覺可以作為上述三種主流分割槽的補充。

間隔分割槽(Interval Partition)

你有沒有想過使用範圍分割槽,隨著時間的增長,你會不停的手動增加新的分割槽。間隔分割槽就是解決這種業務場景,當滿足條件後,會自動增加分割槽。

PARTITION BY RANGE(CDATE) INERVAL (NUMTOYMINTERVAL(1,'mouth'))(
	PARTITION par_test_2017_q1 VALUES LESS THAN (TO_DATE('20170401','yyyymmdd'))
)ENABLE ROW MOVEMENT;

格式:NumToYMInterval(n, interval_unit);
n: 數值型別
interval_unit: ‘YEAR’, ‘MONTH’ ,或其他可以轉換成這兩個值之一的表示式

NumToYMInterval(1, ‘YEAR’) :一年後的間隔
NumToYMInterval(-1, ‘MONTH’): 一個月前

系統分割槽(System Partition)

系統分割槽不指定分割槽條件,而是在SQL裡指定插入哪個分割槽。

PARTITION BY SYSTEM(
	PARTITION par_test_01,
	PARTITION par_test_02
)

虛擬列分割槽

這種虛擬列資料不實際存在磁碟中,而是在SQL計算時實時得到,虛擬列可以和普通列一樣,建索引、做分割槽鍵,收集資訊。

CREATE TABLE test(
	ID NUMBER,
	BUY NUMBER,
	SELL NUMBER,
	GAIN NUMBER AS (SELL-BUY)
)
PARTITION BY RANGE(GAIN)(
	PARTITION par_test_01 VALUES LESS THAN (10000),
	PARTITION par_test_02 VALUES LESS THAN (20000),
	PARTITION par_test_max VALUES LESS THAN (maxvalue)
)

關聯分割槽(Reference Partition)

主表分割槽、子表分割槽。主表變了以後,子表會自動適應。這個以後在討論,感覺目前用的不多。知道這個概念即可。