【DB筆試面試470】分區表有什麼優點?分區表有哪幾類?如何選擇用哪種類型的分區表?
- 2019 年 10 月 11 日
- 筆記
題目部分
分區表有什麼優點?分區表有哪幾類?如何選擇用哪種類型的分區表?
答案部分
當表中的數據量不斷增大時,查詢數據的速度就會變慢,應用程式的性能就會下降,這時就應該考慮對錶進行分區。當對錶進行分區後,在邏輯上,表仍然是一張完整的表,只是將表中的數據在物理上可能存放到多個表空間或物理文件上。當查詢數據時,不至於每次都掃描整張表。Oracle可以將大表或索引分成若干個更小、更方便管理的部分,每一部分稱為一個分區,這樣的表稱為分區表。SQL語句使用分區表比全表能提供更好的數據處理與訪問的性能。即使某些分區不可用,其它分區仍然可用,這叫做分區獨立性。
分區表的一些限制條件:
① 簇表不能進行分區。
② 不能分割含有LONG或LONG RAW列的表。
③ 索引組織表不能進行範圍分區。
何時考慮分區?
對大表進行分區,將有益於大表操作的性能和大表的數據的維護。官方文檔說通常當表的大小超過2GB,或對於OLTP系統,當表的記錄超過1000萬時,都應考慮對錶進行分區。
分區表有什麼優點?
分區表有如下的優點:
① 增強可用性:如果表的一個分區由於系統故障而不能使用,那麼表的其餘好的分區仍可以使用。
② 減少關閉時間:如果系統故障隻影響表的一部分分區,那麼只有這部分分區需要修復,可能比整個大表修復花的時間更少。
③ 維護輕鬆:單獨管理每個分區比管理單個大表要輕鬆得多。
④ 均衡I/O:可以把表的不同分區分配到不同的磁碟來平衡I/O,改善性能。
⑤ 改善性能:對大表的查詢、增加、修改等操作可以分解到表的不同分區來並行執行,可使運行速度更快。
⑥ 分區對用戶透明,最終用戶感覺不到分區的存在。
有哪些類型的分區?如何選擇用哪種類型的分區表?
Oracle的分區可以分為:
● 範圍分區(RANGE PARTITION)
● 哈希分區(HASH PARTITION)
● 列表分區(LIST PARTITION)
● 引用分區(REFERENCE PARTITION)
● 複合分區(組合分區)
● INTERVAL分區(間隔分區)
● 系統分區
INTERVAL分區和系統分區是Oracle 11g的新特性,由於篇幅原因,本書中不講解這2個分區,讀者可自行查閱官方文檔進行學習。尤其對於INTERVAL分區在生產環境中還是比較實用的。下面作者將對範圍、哈希、列表和複合分區分別進行講解。
1、RANGE(範圍)分區
在如下幾種情況下會使用到範圍分區:
(1)頻繁地被一個時間範圍謂詞掃描。
(2)維護一個時間滾動的數據窗口(Rolling Window Of Data)。
(3)保存歷史數據的表。
例如,在下面的例子中,給數據表SALE_DATA在時間欄位SALES_DATE上按照每個月一個分區的方式來創建一個範圍分區。
CREATE TABLE SALE_DATA (SALE_ID NUMBER(5), SALESMAN_NAME VARCHAR2(30), SALES_AMOUNT NUMBER(10), SALES_DATE DATE) PARTITION BY RANGE(SALES_DATE) ( PARTITION SALES_2009_1 VALUES LESS THAN(TO_DATE('01/02/2009','DD/MM/YYYY')), PARTITION SALES_2009_2 VALUES LESS THAN(TO_DATE('01/03/2009','DD/MM/YYYY')), PARTITION SALES_2009_3 VALUES LESS THAN(TO_DATE('01/04/2009','DD/MM/YYYY')), PARTITION SALES_2009_4 VALUES LESS THAN(TO_DATE('01/05/2009','DD/MM/YYYY')), PARTITION SALES_2009_5 VALUES LESS THAN(TO_DATE('01/06/2009','DD/MM/YYYY')), PARTITION SALES_2009_6 VALUES LESS THAN(TO_DATE('01/07/2009','DD/MM/YYYY')), PARTITION SALES_2009_7 VALUES LESS THAN(TO_DATE('01/08/2009','DD/MM/YYYY')), PARTITION SALES_2009_8 VALUES LESS THAN(TO_DATE('01/09/2009','DD/MM/YYYY')), PARTITION SALES_2009_9 VALUES LESS THAN(TO_DATE('01/10/2009','DD/MM/YYYY')), PARTITION SALES_2009_10 VALUES LESS THAN(TO_DATE('01/11/2009','DD/MM/YYYY')), PARTITION SALES_2009_11 VALUES LESS THAN(TO_DATE('01/12/2009','DD/MM/YYYY')), PARTITION SALES_2009_12 VALUES LESS THAN(TO_DATE('01/01/2010','DD/MM/YYYY')), PARTITION SALES_2010_1 VALUES LESS THAN(TO_DATE('01/02/2010','DD/MM/YYYY')) );
這樣就可以非常方便地來管理每個月的數據了。例如,要刪除1年前的數據,只需要寫一個JOB來做定時檢查,如果發現有分區是1年以前的,那麼就可以直接將它刪除,這樣的操作對用戶是不可見的。
例如,要刪除2009年第1個月的分區數據,就可以使用這樣的命令:ALTER TABLE SALE_DATA DROP PARTITION SALES_2009_1;。
2、HASH(哈希)分區
HASH分區有如下的優點:
(1) 提高了大表的高可用性和可管理性。
(2) 可以避免數據傾斜,將數據均勻地分布在多個物理設備上,最大化I/O吞吐量。
(3) 分區修剪和分區智慧連接。
(4) 要求分區鍵是高基數列。
(5) 分區修剪不支援基於分區欄位的範圍查詢,只支援等值查詢或IN-LIST查詢。
HASH分區能夠很容易對數據進行分區,因為語法很簡單,很容易實現。在下面這種情況下,使用HASH分區比RANGE分區更好:
(1) 事先不知道需要將多少數據映射到給定範圍的時候。
(2) 分區的範圍大小很難確定,或者很難平衡的時候。
(3) RANGE分區使數據得到不期望的聚集時。
(4) 性能特性,如並行DML、分區修剪和分區連接很重要的時候。
下面的示例創建了一個HASH分區表:
CREATE TABLE T_HASH PARTITION BY HASH(OBJECT_ID) PARTITIONS 8 AS SELECT * FROM DBA_OBJECTS;
上面的SQL語句創建了一個8個分區的表T_HASH,分區類型為哈希分區,按照Oracle官方的要求,分區的數量應該是2的N次方為合適,例如2,4,8…,這裡是8個分區。
從視圖DBA_TAB_PARTITIONS中可以查詢到分區的詳細情況:
SELECT * FROM DBA_TAB_PARTITIONS D WHERE D.TABLE_OWNER NOT IN ('SYS', 'SYSTEM') AND D.TABLE_NAME='T_HASH' ORDER BY D.TABLE_NAME, D.PARTITION_POSITION, D.PARTITION_NAME; SELECT PARTITION_NAME, COUNT(*) FROM USER_EXTENTS WHERE SEGMENT_NAME = 'T_HASH' GROUP BY PARTITION_NAME; 上面是每個分區物理上佔用的EXTENTS數。 SELECT COUNT(*) FROM T_HASH PARTITION(SYS_P21) UNION ALL SELECT COUNT(*) FROM T_HASH PARTITION(SYS_P22) UNION ALL SELECT COUNT(*) FROM T_HASH PARTITION(SYS_P23) UNION ALL SELECT COUNT(*) FROM T_HASH PARTITION(SYS_P24) UNION ALL SELECT COUNT(*) FROM T_HASH PARTITION(SYS_P25) UNION ALL SELECT COUNT(*) FROM T_HASH PARTITION(SYS_P26) UNION ALL SELECT COUNT(*) FROM T_HASH PARTITION(SYS_P27) UNION ALL SELECT COUNT(*) FROM T_HASH PARTITION(SYS_P28);
在上面的例子中,不論是從EXTENT佔用的空間數量,還是分區中的數據量,都可以看出,數據在各個分區上分布是非常均勻的。
3、列表分區
列表分區(LIST PARTITION)提供了一種按照欄位的值來進行分區的方法,這種方法非常適合於有高重複率欄位值的表。通過這種方法,可以非常方便地控制將某些特定的數值存放到一個分區。
列表分區有如下特點:
(1) 列表值是離散的。
(2) 列表值是無序的,例如:PARTITION PART_01 VALUES('A','E','F')等。
(3) 分區鍵僅能包含一個列。
(4) 列表值是低基數的。
下面的例子創建了一個列表分區:
CREATE TABLE SALES_LIST (SALESMAN_ID NUMBER(5), SALESMAN_NAME VARCHAR2(30), SALES_STATE VARCHAR2(20), SALES_AMOUNT NUMBER(10), SALES_DATE DATE) PARTITION BY LIST(SALES_STATE) (PARTITION SALES_WEST VALUES('CALIFORNIA', 'HAWAII') , PARTITION SALES_EAST VALUES('NEW YORK', 'VIRGINIA', 'FLORIDA'), PARTITION SALES_CENTRAL VALUES('TEXAS', 'ILLINOIS') , PARTITION SALES_OTHER VALUES(DEFAULT) );
在欄位SALES_STATE上創建了列表分區,同時設定了這樣的對應關係:
SALES_WEST('CALIFORNIA','HAWAII') SALES_EAST('NEWYORK','VIRGINIA', 'FLORIDA') SALES_CENTRAL('TEXAS','ILLINOIS')
從分區的名字上就能猜出裡面的內容了,例如SALES_WEST(西部地區)包含了「CALIFORNIA」和「HAWAII」,這對於內容重複率很高,並且可能有一些共性的欄位,使用列表分區是有用處的,它有利於數據的管理,例如想導出或者備份西部地區的數據,可以直接操作SALES_WEST分區,非常方便。
4、複合分區
如果某表按照某列分區之後,仍然較大,或者是有一些其它的需求,那麼還可以通過在分區內再建子分區的方式將分區再分區,即複合分區的方式。
複合分區在Oracle 11g之前有兩種:RANGE-HASH與RANGE-LIST。需要注意的是其順序,根分區只能是RANGE分區,子分區可以是HASH分區或LIST分區,而Oracle 11g在複合分區功能這塊有所增強,又推出了RANGE-RANGE、LIST-RANGE、LIST-LIST和LIST-HASH,這就相當於除HASH外三種分區方式的笛卡爾形式都有了,即目前一共有6種分區,但根分區只能是RANGE分區或LIST分區。
在某些時候按照業務要求,上面的幾種分區也可以按照一定的目的創建組合分區,或者叫子分區。下面的例子創建了一個範圍-列表組合分區:
CREATE TABLE T_RANGE_LIST(ID INT,NAME VARCHAR2(100)) PARTITION BY RANGE(ID) SUBPARTITION BY LIST(NAME) ( PARTITION P1 VALUES LESS THAN(5) (SUBPARTITION SP1 VALUES ('A,B,C'), SUBPARTITION SP2 VALUES ('D,E,F') ), PARTITION P2 VALUES LESS THAN(10) ( SUBPARTITION SP3 VALUES ('A,B,C'), SUBPARTITION SP4 VALUES ('D,E,F') ), PARTITION P3 VALUES LESS THAN(15) ); SELECT * FROM DBA_PART_TABLES D WHERE D.TABLE_NAME = 'T_RANGE_LIST';
對於海量數據的資料庫設計,分區的設計非常重要。例如,對於一個大表,應該採用哪種類型的分區,對於以後資料庫的性能和管理至關重要。
其實,範圍分區、HASH分區和列表分區這三種分區的特點都非常明顯,如下所示:
l 如果需要進行數據的過期化處理,那麼範圍分區基本上是唯一的選擇。
l 如果需要數據的均勻分布,那麼可以考慮使用HASH分區。
l 如果數據的值可以很好地對應於某個分區,那麼就可以考慮使用列表分區。
在上面的原則基礎上,再結合性能的影響因素,來最終確定使用哪種類型的分區。
如果選擇的分區不能確保各分區內數據量的基本平均,那麼這種分區方式有可能是不恰當的。比如對於RANGE分區,假設分了10個分區,而其中一個分區中的記錄數佔總記錄數的90%,其它9個分區只佔總記錄數的10%,則這個分區方式就起不到數據平衡的作用。
本文選自《Oracle程式設計師面試筆試寶典》,作者:李華榮。
About Me:小麥苗
● 本文作者:小麥苗,只專註於資料庫的技術,更注重技術的運用
● 作者部落格地址:http://blog.itpub.net/26736162/abstract/1/
● 本系列題目來源於作者的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解
● 版權所有,歡迎分享本文,轉載請保留出處
● 題目解答若有不當之處,還望各位朋友批評指正,共同進步