1.分區(qū)表的維護(hù)注意事項
- 若分區(qū)表跨不同表空間,做導(dǎo)出、導(dǎo)入時目標(biāo)數(shù)據(jù)庫必須預(yù)建這些表空間。分表區(qū)各區(qū)所在表空間在做導(dǎo)入時目標(biāo)數(shù)據(jù)庫一定要預(yù)建這些表空間!這些表空間不一定是用戶的默認(rèn)表空間,只要存在即可。如果有一個不存在,就會報錯!
- 默認(rèn)時,對分區(qū)表的許多表維護(hù)操作會使全局索引不可用,標(biāo)記成UNUSABLE。 那么就必須重建整個全局索引或其全部分區(qū)。如果已被分區(qū),Oracle 允許在用于維護(hù)操作的ALTER TABLE 語句中指定UPDATE GLOBAL INDEXES 來重載這個默認(rèn)特性,指定這個子句也就告訴Oracle 當(dāng)它執(zhí)行維護(hù)操作的DDL 語句時更新全局索引,這提供了如下好處:
- 在操作基礎(chǔ)表的同時更新全局索引這就不需要后來單獨(dú)地重建全局索引;
- 因為沒有被標(biāo)記成UNUSABLE, 所以全局索引的可用性更高了,甚至正在執(zhí)行分區(qū)的DDL 語句時仍然可用索引來訪問表中的其他分區(qū),避免了查詢所有失效的全局索引的名字以便重建它們;
另外在指定UPDATE GLOBAL INDEXES 之前還要考慮如下性能因素:
- 因為要更新事先被標(biāo)記成UNUSABLE 的索引,所以分區(qū)的DDL 語句要執(zhí)行更長時間,當(dāng)然這要與先不更新索引而執(zhí)行DDL 然后再重建索引所花的時間做個比較,一個適用的規(guī)則是如果分區(qū)的大小小于表的大小的5% ,則更新索引更快一點(diǎn);
- DROP TRUNCATE 和EXCHANGE 操作也不那么快了,同樣這必須與先執(zhí)行DDL 然后再重建所有全局索引所花的時間做個比較;
- 要登記對索引的更新并產(chǎn)生重做記錄和撤消記錄,重建整個索引時可選擇NOLOGGING;
- 重建整個索引產(chǎn)生一個更有效的索引,因為這更利于使用空間,再者重建索引時允許修改存儲選項;
- 分區(qū)索引結(jié)構(gòu)表不支持UPDATE GLOBAL INDEXES 子句。
2.普通表變?yōu)榉謪^(qū)表
將已存在數(shù)據(jù)的普通表轉(zhuǎn)變?yōu)榉謪^(qū)表,沒有辦法通過修改屬性的方式直接轉(zhuǎn)化為分區(qū)表,必須通過重建的方式進(jìn)行轉(zhuǎn)變,一般可以有三種方法,視不同場景使用:
2.1方法一:利用原表重建分區(qū)表。
CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO t
SELECT Rownum, SYSDATE - Rownum FROM Dba_Objects WHERE Rownum <= 5000;
COMMIT;
CREATE TABLE T_NEW (ID, TIME) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('2000-1-1', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (TO_DATE('2002-1-1', 'YYYY-MM-DD')),
PARTITION P3 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),
PARTITION P4 VALUES LESS THAN (MAXVALUE))
AS SELECT ID, TIME FROM T;
RENAME T TO T_OLD;
RENAME T_NEW TO T;
優(yōu)點(diǎn):方法簡單易用,由于采用DDL語句,不會產(chǎn)生UNDO,且只產(chǎn)生少量REDO,效率相對較高,而且建表完成后數(shù)據(jù)已經(jīng)在分布到各個分區(qū)中了。
不足:對于數(shù)據(jù)的一致性方面還需要額外的考慮。由于幾乎沒有辦法通過手工鎖定T表的方式保證一致性,在執(zhí)行CREATE TABLE語句和RENAME T_NEW TO T語句直接的修改可能會丟失,如果要保證一致性,需要在執(zhí)行完語句后對數(shù)據(jù)進(jìn)行檢查,而這個代價是比較大的。另外在執(zhí)行兩個RENAME語句之間執(zhí)行的對T的訪問會失敗。
適用性:適用于修改不頻繁的表,在閑時進(jìn)行操作,表的數(shù)據(jù)量不宜太大。
2.2方法二:使用交換分區(qū)的方法
Drop table t;
CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO t
SELECT Rownum, SYSDATE - Rownum FROM Dba_Objects WHERE Rownum <= 5000;
COMMIT;
CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('2005-9-1', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (MAXVALUE));
ALTER TABLE T_NEW EXCHANGE PARTITION P1 WITH TABLE T;
RENAME T TO T_OLD;
RENAME T_NEW TO T;
優(yōu)點(diǎn):只是對數(shù)據(jù)字典中分區(qū)和表的定義進(jìn)行了修改,沒有數(shù)據(jù)的修改或復(fù)制,效率最高。如果對數(shù)據(jù)在分區(qū)中的分布沒有進(jìn)一步要求的話,實(shí)現(xiàn)比較簡單。在執(zhí)行完RENAME操作后,可以檢查T_OLD中是否存在數(shù)據(jù),如果存在的話,直接將這些數(shù)據(jù)插入到T中,可以保證對T插入的操作不會丟失。
不足:仍然存在一致性問題,交換分區(qū)之后RENAME T_NEW TO T之前,查詢、更新和刪除會出現(xiàn)錯誤或訪問不到數(shù)據(jù)。如果要求數(shù)據(jù)分布到多個分區(qū)中,則需要進(jìn)行分區(qū)的SPLIT操作,會增加操作的復(fù)雜度,效率也會降低。
適用性:適用于包含大數(shù)據(jù)量的表轉(zhuǎn)到分區(qū)表中的一個分區(qū)的操作。應(yīng)盡量在閑時進(jìn)行操作。
2.3方法三:Oracle9i以上版本,利用在線重定義功能
Drop table t;
CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO T
SELECT ROWNUM, SYSDATE - ROWNUM FROM DBA_OBJECTS WHERE ROWNUM <= 5000;
COMMIT;
EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(USER, 'T');
PL/SQL 過程已成功完成。
CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('2004-7-1', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),
PARTITION P3 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')),
PARTITION P4 VALUES LESS THAN (MAXVALUE));
表已創(chuàng)建。
EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'T', 'T_NEW');
PL/SQL 過程已成功完成。
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(USER, 'T', 'T_NEW');
PL/SQL 過程已成功完成。
優(yōu)點(diǎn):保證數(shù)據(jù)的一致性,在大部分時間內(nèi),表T都可以正常進(jìn)行DML操作。只在切換的瞬間鎖表,具有很高的可用性。這種方法具有很強(qiáng)的靈活性,對各種不同的需要都能滿足。而且,可以在切換前進(jìn)行相應(yīng)的授權(quán)并建立各種約束,可以做到切換完成后不再需要任何額外的管理操作。
不足:實(shí)現(xiàn)上比上面兩種略顯復(fù)雜。
適用性:適用于各種情況。
這里只給出了在線重定義表的一個最簡單的例子,詳細(xì)的描述和例子可以參考下面兩篇文章。
Oracle的在線重定義表功能:http://blog.itpub.net/post/468/12855
Oracle的在線重定義表功能(二):http://blog.itpub.net/post/468/12962
2.4把一個已存在數(shù)據(jù)的大表改成分區(qū)表:
第一種(表不是太大):
--1.把原表改名:
rename xsb1 to xsb2;
--2.創(chuàng)建分區(qū)表:
CREATE TABLE xsb1
PARTITION BY LIST (c_test)
(PARTITION xsb1_p1 VALUES (1),
PARTITION xsb1_p2 VALUES (2),
PARTITION xsb1_p0 VALUES (default))
nologging AS SELECT * FROM xsb2;
--3.將原表上的觸發(fā)器、主鍵、索引等應(yīng)用到分區(qū)表上;
--4.刪除原表:
drop table xsb2;
第二種(表很大):
--1. 創(chuàng)建分區(qū)表:
CREATE TABLE x PARTITION BY LIST (c_test) [range ()]
(PARTITION p0 VALUES [less than ](1) tablespace tbs1,
PARTITION p2 VALUES (2) tablespace tbs1,
PARTITION xsb1_p0 VALUES ([maxvalue]default))
AS SELECT * FROM xsb2 [where 1=2];
--2. 交換分區(qū)
alter table x exchange partition p0 with table bsvcbusrundatald ;
--3. 原表改名
alter table bsvcbusrundatald rename to x0;
--4. 新表改名
alter table x rename to bsvcbusrundatald ;
--5. 刪除原表
drop table x0;
--6. 創(chuàng)建新表觸發(fā)器和索引
create index ind_busrundata_lp on bsvcbusrundatald(。。。) local tablespace tbs_brd_ind ;
或者:
1. 規(guī)劃原大表中數(shù)據(jù)分區(qū)的界限,原則上將原表中近期少量數(shù)據(jù)復(fù)制至另一表;
2. 暫停原大表中的相關(guān)觸發(fā)器;
3. 刪除原大表中近期數(shù)據(jù);
4. 改名原大表名稱;
5. 創(chuàng)建分區(qū)表;
6. 交換分區(qū);
7. 重建相關(guān)索引及觸發(fā)器(先刪除之再重建).
參考腳本:
select count(*) from t1 where recdate>sysdate-2;
create table x2 nologging as select * from t1 where recdate>trunc(sysdate-2);
alter triger trg_t1 disable;
delete t1 where recdate>sysdate-2;
commit;
rename t1 to x1;
create table t1 [nologging] partition by range(recdate)
(partition pbefore values less than (trunc(sysdate-2)),
partition pmax values less than (maxvalue))
as select * from x1 where 1=2;
alter table t1 exchange partition pbefore with table x1;
alter table t1 exchange partition pmax with table x2;
drop table x2;
--重建觸發(fā)器
drop table x1;
3.分區(qū)的方法:
- 范圍分區(qū)Range
- 散列分區(qū)Hash
- 列表分區(qū)List
- 組合范圍-散列分區(qū)Range-Hash
- 組合范圍-列表分區(qū)Range-List
可對索引和表分區(qū)。全局索引只能按范圍分區(qū),但可以將其定義在任何類型的分區(qū)或非分區(qū)表上。通常全局索引比局部索引需要更多的維護(hù)。
一般組建局部索引,以便反映其基礎(chǔ)表的結(jié)構(gòu)。它與基礎(chǔ)表是等同分區(qū)的,即它與基礎(chǔ)表在同樣的列上分區(qū),創(chuàng)建同樣數(shù)量的分區(qū)或子分區(qū),設(shè)置與基礎(chǔ)表相對應(yīng)的同樣的分區(qū)邊界。對局部索引而言,當(dāng)維護(hù)活動影響分區(qū)時,會自動維護(hù)索引分區(qū)。這保證了索引與基礎(chǔ)表之間的等同分區(qū)。
關(guān)于范圍分區(qū)Range:
要想將行映射到基于列值范圍的分區(qū),就使用范圍分區(qū)方法。當(dāng)數(shù)據(jù)可以被劃分成邏輯范圍時如年度中的月份,這種類型的分區(qū)就有用了。當(dāng)數(shù)據(jù)在整個范圍中能被均等地劃分時性能最好。如果靠范圍的分區(qū)會由于不均等的劃分而導(dǎo)致分區(qū)在大小上明顯不同時,就需要考慮其他的分區(qū)方法。
關(guān)于散列分區(qū)Hash:
如果數(shù)據(jù)不那么容易進(jìn)行范圍分區(qū),但為了性能和管理的原因又想分區(qū)時,就使用散列分區(qū)方法。散列分區(qū)提供了一種在指定數(shù)量的分區(qū)中均等地劃分?jǐn)?shù)據(jù)的方法。基于分區(qū)鍵的散列值將行映射到分區(qū)中。創(chuàng)建和使用散列分區(qū)會給你提供了一種很靈活的放置數(shù)據(jù)的方法,因為你可以通過在I/O 驅(qū)動器之間播撒(摘掉)這些均等定量的分區(qū),來影響可用性和性能。
關(guān)于列表分區(qū)List:
當(dāng)你需要明確地控制如何將行映射到分區(qū)時,就使用列表分區(qū)方法。可以在每個分區(qū)的描述中為該分區(qū)列指定一列離散值,這不同于范圍分區(qū),在那里一個范圍與一個分區(qū)相關(guān),這也不同于散列分區(qū),在那里用戶不能控制如何將行映射到分區(qū)。列表分區(qū)方法是特意為遵從離散值的模塊化數(shù)據(jù)劃分而設(shè)計的。范圍分區(qū)或散列分區(qū)不那么容易做到這一點(diǎn)。進(jìn)一步說列表分區(qū)可以非常自然地將無序的和不相關(guān)的數(shù)據(jù)集進(jìn)行分組和組織到一起。
與范圍分區(qū)和散列分區(qū)所不同,列表分區(qū)不支持多列分區(qū)。如果要將表按列分區(qū),那么分區(qū)鍵就只能由表的一個單獨(dú)的列組成,然而可以用范圍分區(qū)或散列分區(qū)方法進(jìn)行分區(qū)的所有的列,都可以用列表分區(qū)方法進(jìn)行分區(qū)。
關(guān)于組合范圍-散列分區(qū):
范圍和散列技術(shù)的組合,首先對表進(jìn)行范圍分區(qū),然后用散列技術(shù)對每個范圍分區(qū)再次分區(qū)。給定的范圍分區(qū)的所有子分區(qū)加在一起表示數(shù)據(jù)的邏輯子集。
關(guān)于組合范圍-列表分區(qū):
范圍和列表技術(shù)的組合,首先對表進(jìn)行范圍分區(qū),然后用列表技術(shù)對每個范圍分區(qū)再次分區(qū)。與組合范圍-散列分區(qū)不同的是,每個子分區(qū)的所有內(nèi)容表示數(shù)據(jù)的邏輯子集,由適當(dāng)?shù)姆秶土斜矸謪^(qū)設(shè)置來描述。
注意:創(chuàng)建或更改分區(qū)表時可以指定行移動子句,即ENABLE ROW MOVEMENT 或者DISABLE ROW MOVEMENT ,當(dāng)其鍵被更改時,該子句啟用或停用將行遷移到一個新的分區(qū)。默認(rèn)值為DISABLE ROW MOVEMENT。
如果表中預(yù)期的數(shù)據(jù)量較大,通常都需要考慮使用分區(qū)表,確定使用分區(qū)表后,還要確定什么類型的分區(qū)(range partition、hash partition、list partition等)、分區(qū)區(qū)間大小等。分區(qū)的創(chuàng)建最好與程序有某種默契,比如創(chuàng)建一個分區(qū)表,按自然月份定義分區(qū)的,但程序卻在查詢時默認(rèn)的開始時間與結(jié)束時間是:當(dāng)前日期-30至當(dāng)前日期,比如當(dāng)天是9.18號,那查詢條件被產(chǎn)生為8.18-9.18,結(jié)果分區(qū)后并不沒有大幅提高性能。為此將程序的查詢?nèi)掌谧隽苏{(diào)整,按自然月查詢,系統(tǒng)的負(fù)載小了很多。
4.補(bǔ)充資料
從Oracle8.0開始支持表分區(qū)(MSSQL2005開始支持表分區(qū))。
Oracle9i 分區(qū)能夠提高許多應(yīng)用程序的可管理性、性能與可用性。分區(qū)可以將表、索引及索引編排表進(jìn)一步劃分,從而可以更精細(xì)地對這些數(shù)據(jù)庫對象進(jìn)行管理和訪問。Oracle 提供了種類繁多的分區(qū)方案以滿足所有的業(yè)務(wù)需要。另外,由于在 SQL 語句中是完全透明的,所以分區(qū)可以用于幾乎所有的應(yīng)用程序。
分區(qū)表允許將數(shù)據(jù)分成被稱為分區(qū)甚至子分區(qū)的更小的更好管理的塊。索引也可以這么分區(qū)。每個分區(qū)可以被單獨(dú)管理,可以不依賴于其他分區(qū)而單獨(dú)發(fā)揮作用,因此提供了一個更有利于可用性和性能的結(jié)構(gòu)。
分區(qū)可以提高可管理性、性能與可用性,從而給各種各樣的應(yīng)用程序帶來極大的好處。通常,分區(qū)可以使某些查詢以及維護(hù)操作的性能大大提高。此外,分區(qū)還能夠在很大程度上簡化日常管理任務(wù)。分區(qū)還使數(shù)據(jù)庫設(shè)計人員和管理員能夠解決尖端應(yīng)用程序帶來的最難的問題。分區(qū)是建立上億萬字節(jié)數(shù)據(jù)系統(tǒng)或需要極高可用性系統(tǒng)的關(guān)鍵工具。
在多CPU配置環(huán)境下,如果打算使用并行執(zhí)行,則分區(qū)提供了另一種并行的方法。通過給表或索引的不同分區(qū)分配不同的并行執(zhí)行服務(wù)器,就可以并行執(zhí)行對分區(qū)表和分區(qū)索引的操作。
表或索引的分區(qū)和子分區(qū)都共享相同的邏輯屬性。例如表的所有分區(qū)或子分區(qū)共享相同的列和約束定義,一個索引的分區(qū)或子分區(qū)共享相同的索引選項。然而它們可以具有不同的物理屬性如表空間。
盡管不需要將表或索引的每個分區(qū)或子分區(qū)放在不同的表空間,但這樣做更好。將分區(qū)存儲到不同的表空間能夠:
- 減少數(shù)據(jù)在多個分區(qū)中沖突的可能性
- 可以單獨(dú)備份和恢復(fù)每個分區(qū)
- 控制分區(qū)與磁盤驅(qū)動器之間的映射對平衡I/O 負(fù)載是重要的
- 改善可管理性可用性和性能
分區(qū)操作對現(xiàn)存的應(yīng)用和運(yùn)行在分區(qū)表上的標(biāo)準(zhǔn)DML 語句來說是透明的。但是可以通過在DML 中使用分區(qū)擴(kuò)展表或索引的名字來對應(yīng)用編程,使其利用分區(qū)的優(yōu)點(diǎn)。
可以使用SQL*Loader、Import 和Export 工具來裝載或卸載分區(qū)表中的數(shù)據(jù)。這些工具都是支持分區(qū)和子分區(qū)的。
4.1分區(qū)技術(shù)能夠提高數(shù)據(jù)庫的可管理性:
使用分區(qū)技術(shù),維護(hù)操作可集中于表的特定部分。例如,數(shù)據(jù)庫管理員可以只對表的一部分做備份,而不必對整個表做備份。對整個數(shù)據(jù)庫對象的維護(hù)操作,可以在每個分區(qū)的基礎(chǔ)上進(jìn)行,從而將維護(hù)工作分解成更容易管理的小塊。
分區(qū)技術(shù)提高可管理性的一個典型用法是支持?jǐn)?shù)據(jù)倉庫中的‘滾動視窗’加載進(jìn)程。假設(shè)數(shù)據(jù)庫管理員每周向表中加載新數(shù)據(jù)。該表可以是范圍分區(qū),以便每個分區(qū)包含一周的數(shù)據(jù)。加載進(jìn)程只是簡單地添加新的分區(qū)。添加一個新分區(qū)的操作比修改整個表效率高很多,因為數(shù)據(jù)庫管理員不需要修改任何其他分區(qū)。從分區(qū)后的表中去除數(shù)據(jù)也是一樣。你只要用一個很簡便快捷的數(shù)據(jù)字典操作刪掉一個分區(qū),而不必發(fā)出使用大量資源和調(diào)動所有要刪除的數(shù)據(jù)的 ‘DELETE’ 命令。
4.2分區(qū)技術(shù)能夠提高數(shù)據(jù)庫的性能:
由于減少了所檢查或操作的數(shù)據(jù)數(shù)量,同時允許并行執(zhí)行,Oracle9i 的分區(qū)功能提供了性能上的優(yōu)勢。這些性能包括:
- 分區(qū)修整:分區(qū)修整是用分區(qū)技術(shù)提高性能的最簡單最有價值的手段。分區(qū)修整常常能夠?qū)⒉樵冃阅芴岣邘讉€數(shù)量級。例如,假定應(yīng)用程序中有包含定單歷史記錄的定單表,該表用周進(jìn)行了分區(qū)。查詢一周的定單只需訪問該定單表的一個分區(qū)。如果該定單表包含兩年的歷史記錄,這個查詢只需要訪問一個而不是一百零四個分區(qū)。該查詢的執(zhí)行速度因為分區(qū)修整而有可能快一百倍。分區(qū)修整能與所有其他 Oracle 性能特性協(xié)作。Oracle 公司將把分區(qū)修整技術(shù)與索引技術(shù)、連結(jié)技術(shù)和并行訪問方法一起聯(lián)合使用。
- 分區(qū)智能聯(lián)接:分區(qū)功能可以通過稱為分區(qū)智能聯(lián)接的技術(shù)提高多表聯(lián)接的性能。當(dāng)兩個表要聯(lián)接在一起,而且每個表都用聯(lián)接關(guān)鍵字來分區(qū)時,就可以使用分區(qū)智能聯(lián)接。分區(qū)智能聯(lián)接將大型聯(lián)接分解成較小的發(fā)生在各個分區(qū)間的聯(lián)接,從而用較少的時間完成全部聯(lián)接。這就給串行和并行的執(zhí)行都能帶來顯著的性能改善。
- 更新和刪除的并行執(zhí)行:分區(qū)功能能夠無限地并行執(zhí)行 UPDATE、DELETE 與 MERGE 語句。當(dāng)訪問分區(qū)或未分區(qū)的數(shù)據(jù)庫對象時Oracle 將并行處理 SELECT 與 INSERT 語句。當(dāng)不使用位圖索引時,也可以對分區(qū)或未分區(qū)的數(shù)據(jù)庫對象并行處理 UPDATE、DELETE 和 MERGE 語句。為了對有位圖索引的對象并行處理那些操作,目標(biāo)表必須先分區(qū)。這些 SQL 語句的并行執(zhí)行可以大大提高性能,特別是提高 UPDATE 與 DELETE 或 MERGE 操作涉及大量數(shù)據(jù)時的性能。
4.3分區(qū)技術(shù)提高可用性:
分區(qū)的數(shù)據(jù)庫對象具有分區(qū)獨(dú)立性。該分區(qū)獨(dú)立性特點(diǎn)可能是高可用性戰(zhàn)略的一個重要部分,例如,如果分區(qū)表的分區(qū)不能用,但該表的所有其他分區(qū)仍然保持在線并可用。那么這個應(yīng)用程序可以繼續(xù)針對該分區(qū)表執(zhí)行查詢和事務(wù)處理,只要不是訪問那個不可用的分區(qū),數(shù)據(jù)庫操作仍然能夠成功運(yùn)行。 數(shù)據(jù)庫管理員可以指定各分區(qū)存放在不同的表空間里,從而讓管理員獨(dú)立于其它表分區(qū)針對每個分區(qū)進(jìn)行備份與恢復(fù)操作。 還有,分區(qū)功能可以減少計劃停機(jī)時間。性能由于分區(qū)功能得到了改善,使數(shù)據(jù)庫管理員在相對較小的批處理窗口完成大型數(shù)據(jù)庫對象的維護(hù)工作。