日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Oracle分区表 (二)

發布時間:2024/8/26 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle分区表 (二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

三. 分區表的其他操作

3.1 添加新的分區

添加新的分區有2中情況:

(1)原分區里邊界是maxvalue或者default。 這種情況下,我們需要把邊界分區drop掉,加上新分區后,在添加上新的分區。 或者采用split,對邊界分區進行拆分。

(2)沒有邊界分區的。 這種情況下,直接添加分區就可以了。

?

以邊界分區添加新分區示例:

(1)分區表和索引的信息如下:

SQL> create table custaddr

? 2? (

? 3??? id???????? varchar2(15 byte)?? not null,

? 4??? areacode?? varchar2(4 byte)

? 5? )

? 6? partition by list (areacode)

? 7? (

? 8??? partition t_list556 values ('556') tablespace icd_service,

? 9??? partition p_other values (default)tablespace icd_service

?10? );

表已創建。

SQL> create index ix_custaddr_id on custaddr(id)

? 2? local (

? 3??? partition t_list556? tablespace icd_service,

? 4??? partition p_other tablespace icd_service

? 5? );

索引已創建。

?

(2)插入幾條測試數據:

SQL> insert into custaddr values('1','556');

已創建 1 行。

SQL> insert into custaddr values('2','551');

已創建 1 行。

SQL> insert into custaddr values('3','555');

已創建 1 行。

SQL> commit;

提交完成。

SQL> select * from custaddr;

ID????????????? AREA

--------------- ----

1?????????????? 556

2?????????????? 551

3?????????????? 555

SQL> select * from custaddr partition(t_list556);

ID????????????? AREA

--------------- ----

1?????????????? 556

SQL>

?

(3)刪除default分區

sql> alter table custaddr drop partition p_other;

表已更改。

sql> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR';

table_name???????????????????? partition_name

------------------------------ ------------------------------

custaddr?????????????????????? t_list556

?

(4)添加新分區

SQL> alter table custaddr add partition t_list551 values('551') tablespace icd_service;

表已更改。

SQL> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR';

?

TABLE_NAME???????????????????? PARTITION_NAME

------------------------------ ------------------------------

CUSTADDR?????????????????????? T_LIST556

CUSTADDR?????????????????????? T_LIST551

(5)添加default 分區

SQL> alter table custaddr add partition p_other values (default)? tablespace icd_service;

表已更改。

SQL> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR';

?

TABLE_NAME???????????????????? PARTITION_NAME

------------------------------ ------------------------------

CUSTADDR?????????????????????? T_LIST556

CUSTADDR?????????????????????? T_LIST551

CUSTADDR?????????????????????? P_OTHER

?

(6)對于局部索引,oracle會自動增加一個局部分區索引。驗證一下:

sql> select owner,index_name,table_name,partitioning_type from dba_part_indexes where index_name='ix_custaddr_id';

owner??????????? index_name?????????? table_name

---------------------- ------------------------------ ------------------

icd???????????? ix_custaddr_id???????? custaddr

sql> select index_owner,index_name,partition_name from dba_ind_partitions? where index_name='ix_custaddr_id';

index_owner?????????? index_name????????????????? partition_name

------------------------------ ------------------------------ ------------------

icd????????????????? ix_custaddr_id???????????????? p_other

icd????????????????? ix_custaddr_id???????????????? t_list551

icd????????????????? ix_custaddr_id???????????????? t_list556

?

分區索引自動創建了。

?

3.2? split 分區拆分

?????? 在3.1 中,我們說明了可以使用split的方式來添加分區。 這里我們用split方法繼續上面的實驗。

?

sql> alter table custaddr split partition p_other values('552') into (partition t_list552 tablespace icd_service, partition p_other tablespace icd_service);

表已更改。

--注意這里紅色的地方,如果是Range類型的,使用at,List使用Values。

SQL> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR';

TABLE_NAME???????????????????? PARTITION_NAME

------------------------------ ------------------------------

CUSTADDR?????????????????????? T_LIST556

CUSTADDR?????????????????????? T_LIST551

CUSTADDR?????????????????????? T_LIST552

CUSTADDR?????????????????????? P_OTHER

?

SQL> select index_owner,index_name,partition_name from dba_ind_partitions? where index_name='IX_CUSTADDR_ID';

?

index_owner???????????? index_name???????????????????? partition_name

------------------------------ ------------------------------ ------------------

icd??????????????????????????? ix_custaddr_id???????????????? p_other

icd??????????????????????????? ix_custaddr_id???????????????? t_list551

icd??????????????????????????? ix_custaddr_id???????????????? t_list552

icd??????????????????????????? ix_custaddr_id???????????????? t_list556

?

注意:分區表會自動維護局部分區索引。全局索引會失效,需要進行rebuild。

?

3.3 合并分區Merge

?????? 相鄰的分區可以merge為一個分區,新分區的下邊界為原來邊界值較低的分區,上邊界為原來邊界值較高的分區,原先的局部索引相應也會合并,全局索引會失效,需要rebuild。

?

SQL> alter table custaddr merge partitions t_list552,p_other into partition p_other;

表已更改。

SQL> select index_owner,index_name,partition_name from dba_ind_partitions? where index_name='IX_CUSTADDR_ID';

index_owner?????? index_name???????? partition_name

--------------------? ------------------------------ ------------------

icd????????????? ix_custaddr_id????????? p_other

icd????????????? ix_custaddr_id????????? t_list551

icd????????????? ix_custaddr_id????????? t_list556

?

SQL> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR';

?

table_name???????????????????? partition_name

------------------------------ ------------------------------

custaddr?????????????????????? t_list556

custaddr?????????????????????? t_list551

custaddr?????????????????????? p_other

?

3.4 . 移動分區

SQL> alter table custaddr move partition P_OTHER tablespace system;

?

表已更改。

SQL> alter table custaddr move partition P_OTHER tablespace icd_service;

表已更改。

?

注意:分區移動會自動維護局部分區索引,oracle不會自動維護全局索引,所以需要我們重新rebuild分區索引,具體需要rebuild哪些索引,可以通過dba_part_indexes,dba_ind_partitions去判斷。

?

SQL> Select index_name,status From user_indexes Where table_name='CUSTADDR';

?

INDEX_NAME???????????????????? STATUS

------------------------------ --------

IX_CUSTADDR_ID???????????????? N/A

?

??????

3.5. Truncate分區

SQL> select * from custaddr partition(T_LIST556);

ID????????????? AREA

--------------- ----

1?????????????? 556

SQL> alter table custaddr truncate partition(T_LIST556);

表被截斷。

SQL> select * from custaddr partition(T_LIST556);

未選定行

?

說明:

?????? Truncate相對delete操作很快,數據倉庫中的大量數據的批量數據加載可能會有用到;截斷分區同樣會自動維護局部分區索引,同時會使全局索引unusable,需要重建

?

3.6.? Drop分區

SQL> alter table custaddr drop partition T_LIST551;

表已更改。

?

SQL> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR';

TABLE_NAME???????????????????? PARTITION_NAME

------------------------------ ------------------------------

CUSTADDR?????????????????????? T_LIST556

CUSTADDR?????????????????????? P_OTHER?????

同樣會自動維護局部分區索引,同時會使全局索引unusable,需要重建

?

?

四. 分區表的索引

?????? 分區索引分為本地(local index)索引和全局索引(global index)。局部索引比全局索引容易管理, 而全局索引比較快。

?

與索引有關的表:

?????? dba_part_indexes 分區索引的概要統計信息,可以得知每個表上有哪些分區索引,分區索引的類型(local/global)

?????? dba_ind_partitions? 每個分區索引的分區級統計信息

?????? dba_indexes/dba_part_indexes 可以得到每個表上有哪些非分區索引

?

?????? Local索引肯定是分區索引,Global索引可以選擇是否分區,如果分區,只能是有前綴的分區索引。

?

分區索引分2類:有前綴(prefix)的分區索引和無前綴(nonprefix)的分區索引:

(1)有前綴的分區索引指包含了分區鍵,并且將其作為引導列的索引。

如:

create index i_id_global on PDBA(id) global? --引導列

? 2? partition by range(id)? --分區鍵

? 3? (partition p1 values less than (200),

? 4? partition p2 values less than (maxvalue)

? 5? );

這里的ID 就是分區鍵,并且分區鍵id 也是索引的引導列。

?

(2)無前綴的分區索引的列不是以分區鍵開頭,或者不包含分區鍵列。

如:

create index ix_custaddr_local_id_p on custaddr(id)

local (?

? partition t_list556 tablespace icd_service,?

? partition p_other tablespace icd_service

)???

?

?????? 這個分區是按照areacode來的。但是索引的引導列是ID。 所以它就是非前綴分區索引。

?

全局分區索引不支持非前綴的分區索引,如果創建,報錯如下:

SQL> create index i_time_global on PDBA(id) global? --索引引導列

? 2? partition by range(time) --分區建

? 3? (partition p1 values less than (TO_DATE('2010-12-1', 'YYYY-MM-DD')),

? 4? partition p2 values less than (maxvalue)

? 5? );

partition by range(time)

?????????????????????? *

第 2 行出現錯誤:

ORA-14038: GLOBAL 分區索引必須加上前綴

?

?

4.1? Local 本地索引

?????? 對于local索引,當表的分區發生變化時,索引的維護由Oracle自動進行。

?

注意事項:

(1) 局部索引一定是分區索引,分區鍵等同于表的分區鍵。

(2) 前綴和非前綴索引都可以支持索引分區消除,前提是查詢的條件中包含索引分區鍵。

(3) 局部索引只支持分區內的唯一性,無法支持表上的唯一性,因此如果要用局部索引去給表做唯一性約束,則約束中必須要包括分區鍵列。

(4) 局部分區索引是對單個分區的,每個分區索引只指向一個表分區;全局索引則不然,一個分區索引能指向n個表分區,同時,一個表分區,也可能指向n個索引分區,對分區表中的某個分區做truncate或者move,shrink等,可能會影響到n個全局索引分區,正因為這點,局部分區索引具有更高的可用性。

(5) 位圖索引必須是局部分區索引。

(6) 局部索引多應用于數據倉庫環境中。

(7) B樹索引和位圖索引都可以分區,但是HASH索引不可以被分區。

?

?

示例:

sql> create index ix_custaddr_local_id on custaddr(id) local;

索引已創建。

?

和下面SQL 效果相同,因為local索引就是分區索引:

create index ix_custaddr_local_id_p on custaddr(id)

local (?

? partition t_list556 tablespace icd_service,?

? partition p_other tablespace icd_service

)???

?

SQL> create index ix_custaddr_local_areacode on custaddr(areacode) local;

索引已創建。

?

驗證2個索引的類型:

SQL> select index_name,table_name,partitioning_type,locality,ALIGNMENT from user_part_indexes where table_name='CUSTADDR';

?

index_name??????????????? table_name partition locali alignment

------------------------------ ---------- --------- ------ ------------

ix_custaddr_local_areacode???? custaddr?? list????? local? prefixed

ix_custaddr_local_id?????????? custaddr?? list????? local? non_prefixed

?

?????? 因為我們的custaddr表是按areacode進行分區的,所以索引ix_custaddr_local_areacode是有前綴的索引(prefixed)。而ix_custaddr_local_id是非前綴索引。

?

4.2? Global索引

?????? 對于global索引,可以選擇是否分區,而且索引的分區可以不與表分區相對應。全局分區索引只能是B樹索引,到目前為止(10gR2),oracle只支持有前綴的全局索引。

?????? 另外oracle不會自動的維護全局分區索引,當我們在對表的分區做修改之后,如果對分區進行維護操作時不加上update global indexes的話,通常會導致全局索引的INVALDED,必須在執行完操作后 REBUILD。??????

?

注意事項:

(1)全局索引可以分區,也可以是不分區索引,全局索引必須是前綴索引,即全局索引的索引列必須是以索引分區鍵作為其前幾列。

(2)全局索引可以依附于分區表;也可以依附于非分區表。

(3)全局分區索引的索引條目可能指向若干個分區,因此,對于全局分區索引,即使只截斷一個分區中的數據,都需要rebulid若干個分區甚至是整個索引。

(4)全局索引多應用于oltp系統中。

(5)全局分區索引只按范圍或者散列分區,hash分區是10g以后才支持。

(6) oracle9i以后對分區表做move或者truncate的時可以用update global indexes語句來同步更新全局分區索引,用消耗一定資源來換取高度的可用性。

(7) 表用a列作分區,索引用b做局部分區索引,若where條件中用b來查詢,那么oracle會掃描所有的表和索引的分區,成本會比分區更高,此時可以考慮用b做全局分區索引。

?

?

注意:Oracle只支持2中類型的全局分區索引:

?????????? range partitioned 和 Hash Partitioned.

?

官網的說明如下:

Global Partitioned Indexes

?????? Oracle offers two types of global partitioned index: range partitioned and hash partitioned.

(1)Global Range Partitioned Indexes

?????? Global range partitioned indexes are flexible in that the degree of partitioning and the partitioning key are independent from the table's partitioning method. They are commonly used for OLTP environments and offer efficient access to any individual record.

?????? The highest partition of a global index must have a partition bound, all of whose values are MAXVALUE. This ensures that all rows in the underlying table can be represented in the index. Global prefixed indexes can be unique or nonunique.

?????? You cannot add a partition to a global index because the highest partition always has a partition bound of MAXVALUE. If you wish to add a new highest partition, use the ALTER INDEX SPLIT PARTITION statement. If a global index partition is empty, you can explicitly drop it by issuing the ALTER INDEX DROP PARTITION statement. If a global index partition contains data, dropping the partition causes the next highest partition to be marked unusable. You cannot drop the highest partition in a global index.

(2)Global Hash Partitioned Indexes

?????? Global hash partitioned indexes improve performance by spreading out contention when the index is monotonically growing. In other words, most of the index insertions occur only on the right edge of an index.

?

(3)Maintenance of Global Partitioned Indexes

?????? By default, the following operations on partitions on a heap-organized table mark all global indexes as unusable:

ADD (HASH)

COALESCE (HASH)

DROP

EXCHANGE

MERGE

MOVE

SPLIT

TRUNCATE

?

示例1 全局索引,全局索引對所有分區類型都支持:

sql> create index ix_custaddr_ global_id on custaddr(id) global;

索引已創建。

?

示例2:全局分區索引,只支持Range 分區和Hash 分區:

?

(1)創建2個測試分區表:

sql> create table pdba (id number, time date) partition by range (time)

? 2? (

? 3? partition p1 values less than (to_date('2010-10-1', 'yyyy-mm-dd')),

? 4? partition p2 values less than (to_date('2010-11-1', 'yyyy-mm-dd')),

? 5? partition p3 values less than (to_date('2010-12-1', 'yyyy-mm-dd')),

? 6? partition p4 values less than (maxvalue)

? 7? );

表已創建。

?

SQL> create table Thash

? 2? (

? 3? id number primary key,

? 4? item_id number(8) not null

? 5? )

? 6? partition by hash(id)

? 7? (

? 8? partition part_01,

? 9? partition part_02,

?10? partition part_03

?11? );

?

表已創建。

?

(2)創建分區索引

?

示例2:全局分區索引

?

SQL> create index i_id_global on PDBA(id) global

? 2? partition by range(id)

? 3? (partition p1 values less than (200),

? 4? partition p2 values less than (maxvalue)

? 5? );

索引已創建。

--這個是有前綴的分區索引。

?

SQL> create index i_time_global on PDBA(id) global

? 2? partition by range(time)

? 3? (partition p1 values less than (TO_DATE('2010-12-1', 'YYYY-MM-DD')),

? 4? partition p2 values less than (maxvalue)

? 5? );

partition by range(time)

?????????????????????? *

第 2 行出現錯誤:

ORA-14038: GLOBAL 分區索引必須加上前綴

?

?

SQL> create index i_time_global on PDBA(time) global

? 2? partition by range(time)

? 3? (partition p1 values less than (TO_DATE('2010-12-1', 'YYYY-MM-DD')),

? 4? partition p2 values less than (maxvalue)

? 5? );

索引已創建。

--有前綴的分區索引

?

SQL> select index_name,table_name,partitioning_type,locality,ALIGNMENT from user_part_indexes where table_name='PDBA';

index_name??????????? table_name partition locali alignment

------------------------------ ---------- --------- ------ ------------

i_id_global???????????? pdba?????? range???? global prefixed

i_time_global?????????? pdba?????? range???? global prefixed

?

SQL> CREATE INDEX ix_hash ON PDBA (id,time) GLOBAL

? 2?????? PARTITION BY HASH (id)

? 3?????? (PARTITION p1,

? 4??????? PARTITION p2,

? 5??????? PARTITION p3,

? 6??????? PARTITION p4);

索引已創建。

?

只要索引的引導列包含分區鍵,就是有前綴的分區索引。

4.3 索引重建問題

(1)分區索引

?????? 對于分區索引,不能整體進行重建,只能對單個分區進行重建。語法如下:

?????? Alter index idx_name rebuild partition index_partition_name [online nologging]

說明:

?????? online:表示重建的時候不會鎖表。

?????? nologging:表示建立索引的時候不生成日志,加快速度。

??????

如果要重建分區索引,只能drop表原索引,在重新創建:

?????? SQL>create index loc_xxxx_col on xxxx(col) local tablespace SYSTEM;

?????? 這個操作要求較大的臨時表空間和排序區。

?

示例:

SQL> select index_name,partition_name from user_ind_partitions where index_name='I_TIME_GLOBAL';

INDEX_NAME???????????????????? PARTITION_NAME

------------------------------ ------------------------------

I_TIME_GLOBAL????????????????? P1

I_TIME_GLOBAL????????????????? P2

SQL>? alter index I_TIME_GLOBAL rebuild partition p1 online nologging;

索引已更改。

SQL> alter index I_TIME_GLOBAL rebuild partition p2 online nologging;

索引已更改。

(2)全局索引

?????? Oracle 會自動維護分區索引,對于全局索引,如果在對分區表操作時,沒有指定update? index,則會導致全局索引失效,需要重建。

SQL> select owner,index_name,table_name,status from dba_indexes where INDEX_NAME='IX_PDBA_GLOBAL';

?owner???????? index_name???????????????????? table_name status

------------------------------ ------------------------------ ---------- -------

sys?????????? ix_pdba_global???????????????? pdba?????? valid

刪除一個分區:

SQL> alter table pdba drop partition p2;

表已更改。

SQL> select owner,index_name,table_name,status from dba_indexes where INDEX_NAME='IX_PDBA_GLOBAL';

owner??????????? index_name????????? table_name status

------------------------------ ------------------------------ ---------- -------

sys???????????? ix_pdba_global???????? pdba?????? valid

split 分區:

SQL> alter table pdba split partition P4 at(TO_DATE('2010-12-21 00:00:00','YYYY-MM-DD HH24:MI:SS')) into (partition P4, partition P5);

表已更改。

SQL> select owner,index_name,table_name,status from dba_indexes where INDEX_NAME='IX_PDBA_GLOBAL';

owner??????? index_name???????????????????? table_name status

------------------------------ ------------------------------ ---------- -------

sys????????? ix_pdba_global???????????????? pdba?????? valid

drop 分區時使用update indexes

SQL> alter table pdba drop partition P4 UPDATE INDEXES;

表已更改。

SQL> select owner,index_name,table_name,status from dba_indexes where INDEX_NAME='IX_PDBA_GLOBAL';

owner????????? index_name?????????? table_name status

---------------------- ------------------------------ ---------- -------

sys???????????? ix_pdba_global??????? pdba?????? valid

做了幾個drop分區操作,全局索引沒有失效,有點奇怪。 不過如果在生產環境中,還是小心點。

?

重建全局索引命令如下:

?????? Alter index idx_name rebuild [online nologging]

?

示例:

SQL> Alter index ix_pdba_global rebuild online nologging;

索引已更改。

補充一點,分區表存儲空間的問題:
SQL> select table_name,partition_name,tablespace_name from user_tab_partitions where table_name='DBA';

TABLE_NAME PARTITION_NAME???????????????? TABLESPACE_NAME
---------- ------------------------------ ------------------------------
DBA??????? P1???????????????????????????? SYSTEM
DBA??????? P2???????????????????????????? SYSTEM
DBA??????? P3???????????????????????????? SYSTEM
DBA??????? P4???????????????????????????? SYSTEM

?

通過user_tab_partitions 表可以查看到每個分區對應的tablesapce_name. 但是,如果通過all_tables 表,卻查不到分區表對應表空間的信息。

分區表:
SQL> select owner,table_name,tablespace_name,cluster_name from all_tables where table_name='DBA';

OWNER TABLE_NAME TABLESPACE_NAME??????????????? CLUSTER_NAME
----- ---------- ------------------------------ -----------------------------------------------------
SYS?? DBA

普通表:
SQL> select owner,table_name,tablespace_name,cluster_name from all_tables where table_name='DAVE';

OWNER TABLE_NAME TABLESPACE_NAME??????????????? CLUSTER_NAME
----- ---------- ------------------------------ ---------------------------------------------------
SYS?? DAVE?????? SYSTEM


?PS:

?????? 在google的時候,發現斯坦福大學(http://stanford.edu/)的文檔庫上有很多Oracle資料。

?????? 國內這塊其他大學沒有留意過,中國科學技術大學(http://www.ustc.edu.cn/)也是有資料庫的

總結

以上是生活随笔為你收集整理的Oracle分区表 (二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。