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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Oracle-分区表解读

發(fā)布時(shí)間:2025/3/21 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle-分区表解读 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

概述

Oracle-OLAP和OLTP解讀

Oracle-index索引解讀

Oracle-分區(qū)表解讀

Oracle-鎖解讀

Oracle-等待事件解讀

Oracle-procedure/cursor解讀


Oracle關(guān)于分區(qū)的在線文檔

當(dāng)表中的數(shù)據(jù)量不斷增大,查詢數(shù)據(jù)的速度就會變慢,應(yīng)用程序的性能就會下降,這時(shí)就應(yīng)該考慮對表進(jìn)行分區(qū)。 表進(jìn)行分區(qū)后,邏輯上表仍然是一張完整的表,只是將表中的數(shù)據(jù)在物理上存放到多個(gè)表空間(物理文件上),這樣查詢數(shù)據(jù)時(shí),不至于每次都掃描整張表。

對于數(shù)據(jù)庫中的超大型表,可通過把它的數(shù)據(jù)分成若干個(gè)小表,從而簡化數(shù)據(jù)庫的管理活動。對于每一個(gè)簡化后的小表,我們稱為一個(gè)單個(gè)的分區(qū)。

對于分區(qū)的訪問,我們不需要使用特殊的SQL查詢語句或特定的DML語句,而且可以單獨(dú)的操作單個(gè)分區(qū),而不是整個(gè)表。同時(shí)可以將不同分區(qū)的數(shù)據(jù)放置到不同的表空間。

Oracle提供分區(qū)技術(shù)以支持VLDB(VeryLargeDataBase).

分區(qū)表通過對分區(qū)列的判斷,把分區(qū)列不同的記錄,放到不同的分區(qū)中。分區(qū)完全對應(yīng)用透明。

對于外部應(yīng)用程序來說,雖然存在不同的分區(qū),且數(shù)據(jù)位于不同的表空間,但邏輯上仍然是一張表。

Oracle的分區(qū)表可以包括多個(gè)分區(qū),每個(gè)分區(qū)都是一個(gè)獨(dú)立的段(SEGMENT),可以存放到不同的表空間中。

查詢時(shí)可以通過查詢表來訪問各個(gè)分區(qū)中的數(shù)據(jù),也可以通過在查詢時(shí)直接指定分區(qū)的方法來進(jìn)行查詢。

在oracle 10g中最多支持:1024k-1個(gè)分區(qū)。

什么時(shí)候需要分區(qū)表?

官網(wǎng)給出的建議:

  • 1、表的大小超過2GB。
  • 2、表中包含歷史數(shù)據(jù),新的數(shù)據(jù)被增加都新的分區(qū)中。需要將歷史數(shù)據(jù)和當(dāng)前的數(shù)據(jù)分開單獨(dú)處理,比如歷史數(shù)據(jù)僅僅需要只讀,而當(dāng)前數(shù)據(jù)則實(shí)現(xiàn)DML

表分區(qū)的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 1、改善查詢性能:只需要搜索特定分區(qū),而非整張表,提高查詢速度。
  • 2、增強(qiáng)可用性:如果表的某個(gè)分區(qū)出現(xiàn)故障,表在其他分區(qū)的數(shù)據(jù)仍然可用;
  • 3、維護(hù)方便:可以單獨(dú)備份和恢復(fù)每個(gè)分區(qū)。如果表的某個(gè)分區(qū)出現(xiàn)故障,需要修復(fù)數(shù)據(jù),只修復(fù)該分區(qū)即可; 節(jié)約維護(hù)時(shí)間,單個(gè)分區(qū)的數(shù)據(jù)裝載,索引重建,備份,維護(hù)等將遠(yuǎn)小于整張表的維護(hù)時(shí)間。
  • 4、均衡I/O:將不同的分區(qū)映射到不同的磁盤以平衡I/O,提高并發(fā),改善整個(gè)系統(tǒng)性能。

缺點(diǎn):

  • 1.已經(jīng)存在的表沒有方法可以直接轉(zhuǎn)化為分區(qū)表。不過 Oracle 提供了在線重定義表的功能。

特點(diǎn)

  • 共性:不同的分區(qū)之間必須有相同的邏輯屬性,比如表名,列名,數(shù)據(jù)類型,約束等,
  • 個(gè)性:各個(gè)分區(qū)可以有不同的物理屬性,比如pctfree, pctused, and tablespaces.
  • 分區(qū)獨(dú)立性:即使某些分區(qū)不可用,其他分區(qū)仍然可用。
  • 特殊性:含有LONG、LONGRAW數(shù)據(jù)類型的表不能進(jìn)行分區(qū)

  • ORACLE分區(qū)類型

    Oracle 10g提供了以下幾種分區(qū)類型:

    • (1)范圍分區(qū)(range);
    • (2)哈希分區(qū)(hash);
    • (3)列表分區(qū)(list);
    • (4)范圍-哈希復(fù)合分區(qū)(range-hash);
    • (5)范圍-列表復(fù)合分區(qū)(range-list)。

    范圍分區(qū)(range)

    范圍分區(qū)特性

    Range分區(qū)是應(yīng)用范圍比較廣的表分區(qū)方式,它是以列的值的范圍來做為分區(qū)的劃分條件,將記錄存放到列值所在的range分區(qū)中,并且分區(qū)鍵經(jīng)常采用日期。

    當(dāng)使用范圍分區(qū)時(shí),請考慮以下幾個(gè)規(guī)則:

    • 1、每一個(gè)分區(qū)都必須有一個(gè)VALUES LESS THEN子句,它指定了一個(gè)不包括在該分區(qū)中的上限值。分區(qū)鍵的任何值等于或者大于這個(gè)上限值的記錄都會被加入到下一個(gè)高一些的分區(qū)中。

    • 2、所有分區(qū),除了第一個(gè),都會有一個(gè)隱式的下限值,這個(gè)值就是此分區(qū)的前一個(gè)分區(qū)的上限值。

    • 3、在最高的分區(qū)中,MAXVALUE被定義。MAXVALUE代表了一個(gè)不確定的值。這個(gè)值高于其它分區(qū)中的任何分區(qū)鍵的值,也可以理解為高于任何分區(qū)中指定的VALUE LESS THEN的值,同時(shí)包括空值。

    如果某些記錄暫無法預(yù)測范圍,可以創(chuàng)建maxvalue分區(qū),所有不在指定范圍內(nèi)的記錄都會被存儲到maxvalue所在分區(qū)中。

    創(chuàng)建范圍分區(qū)時(shí),必須指定以下內(nèi)容
    分區(qū)方法:range
    分區(qū)列
    標(biāo)識分區(qū)邊界的分區(qū)描述

    如:

    create table pdba (id number, time date) partition by range (time) --創(chuàng)建基于日期的范圍分區(qū)并存儲到不同的表空間(partition p1 values less than (to_date('2010-10-1', 'yyyy-mm-dd')),partition p2 values less than (to_date('2010-11-1', 'yyyy-mm-dd')),partition p3 values less than (to_date('2010-12-1', 'yyyy-mm-dd')),partition p4 values less than (maxvalue)) create table r --創(chuàng)建基于值范圍的分區(qū),分區(qū)子句未指定表空間時(shí)則位于缺省的表空間(a int)partition by range (a)(partition p1 values less than (10),partition p2 values less than (20),partition p3 values less than (30),partition p4 values less than (maxvalue));select * from r partition (p1) --查看分區(qū)中的數(shù)據(jù)

    說明:

    partition by 用于指定分區(qū)方式range 表示分區(qū)的方式是范圍劃分partition pn 用于指定分區(qū)的名字values less than 指定分區(qū)的上界(上限)添加分區(qū):ALTER TABLE radd partition p5 values less than (xxx ) tablespace xx;查看分區(qū)表相關(guān)信息:SELECT table_name,partition_name,subpartition_count,tablespace_name,user_stats from user_tab_partitions;

    栗子1

    假設(shè)有一個(gè)CUSTOMER表,表中有數(shù)據(jù)200000行,我們將此表通過CUSTOMER_ID進(jìn)行分區(qū),每個(gè)分區(qū)存儲100000行,我們將每個(gè)分區(qū)保存到單獨(dú)的表空間中,這樣數(shù)據(jù)文件就可以跨越多個(gè)物理磁盤。

    CREATE TABLE CUSTOMER(CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY,FIRST_NAME VARCHAR2(30) NOT NULL,LAST_NAME VARCHAR2(30) NOT NULL,PHONE VARCHAR2(15) NOT NULL,EMAIL VARCHAR2(80),STATUS CHAR(1))PARTITION BY RANGE (CUSTOMER_ID)(PARTITION CUS_PART1 VALUES LESS THAN (100000) TABLESPACE CUS_TS01,PARTITION CUS_PART2 VALUES LESS THAN (200000) TABLESPACE CUS_TS02)

    栗子2-按時(shí)間劃分

    按時(shí)間劃分

    CREATE TABLE ORDER_ACTIVITIES(ORDER_ID NUMBER(7) NOT NULL,ORDER_DATE DATE,TOTAL_AMOUNT NUMBER,CUSTOTMER_ID NUMBER(7),PAID CHAR(1))PARTITION BY RANGE (ORDER_DATE)(PARTITION ORD_ACT_PART01 VALUES LESS THAN (TO_DATE('01-MAY-2016','DD-MON-YYYY')) TABLESPACEORD_TS01,PARTITION ORD_ACT_PART02 VALUES LESS THAN (TO_DATE('01-JUN-2016','DD-MON-YYYY')) TABLESPACE ORD_TS02,PARTITION ORD_ACT_PART02 VALUES LESS THAN (TO_DATE('01-JUL-2016','DD-MON-YYYY')) TABLESPACE ORD_TS03)

    栗子3-MAXVALUE

    CREATE TABLE RangeTable(idd INT PRIMARY KEY ,iNAME VARCHAR(10),grade INT)PARTITION BY RANGE (grade)(PARTITION part1 VALUES LESS THEN (1000) TABLESPACE Part1_tb,PARTITION part2 VALUES LESS THEN (MAXVALUE) TABLESPACE Part2_tb);

    哈希分區(qū)(hash)

    也被成為散列分區(qū)。

    這類分區(qū)是在列值上使用哈希算法,以確定將行放入哪個(gè)分區(qū)中。當(dāng)列的值沒有合適的條件時(shí),建議使用散哈希分區(qū)。

    哈希分區(qū)為通過指定分區(qū)編號來均勻分布數(shù)據(jù)的一種分區(qū)類型,因?yàn)橥ㄟ^在I/O設(shè)備上進(jìn)行散列分區(qū),使得這些分區(qū)大小一致。

    對于那些無法有效劃分范圍的表,可以使用hash分區(qū),這樣對于提高性能還是會有一定的幫助。hash分區(qū)會將表中的數(shù)據(jù)平均分配到你指定的幾個(gè)分區(qū)中,列所在分區(qū)是依據(jù)分區(qū)列的hash值自動分配,因此你并不能控制也不知道哪條記錄會被放到哪個(gè)分區(qū)中,hash分區(qū)也可以支持多個(gè)依賴列。

    創(chuàng)建散列分區(qū)時(shí),必須指定以下信息
    分區(qū)方法:hash
    分區(qū)列
    分區(qū)數(shù)量或單獨(dú)的分區(qū)描述

    分裂、刪除和合并分區(qū)不能應(yīng)用于Hash分區(qū),但是,Hash分區(qū)能夠合并和添加。

    創(chuàng)建hash分區(qū)有兩種方法:一種方法是指定分區(qū)數(shù)量,另一種方法是指定分區(qū)的名字,
    但兩者不能同時(shí)指定。

    CREATE TABLE HASH_TABLE(COL NUMBER(8),INF VARCHAR2(100))PARTITION BY HASH (COL)(PARTITION PART01 TABLESPACE HASH_TS01,PARTITION PART02 TABLESPACE HASH_TS02,PARTITION PART03 TABLESPACE HASH_TS03)

    在這里,我們指定了每個(gè)分區(qū)的表空間。

    簡寫的方式:

    CREATE TABLE emp(empno NUMBER (4),ename VARCHAR2 (30),sal NUMBER)PARTITION BY HASH (empno)PARTITIONS 8 --表空間的數(shù)量STORE IN (emp1,emp2,emp3,emp4,emp5,emp6,emp7,emp8);--表空間的名稱

    hash分區(qū)最主要的機(jī)制是根據(jù)hash算法來計(jì)算具體某條紀(jì)錄應(yīng)該插入到哪個(gè)分區(qū)中,hash算法中最重要的是hash函數(shù),Oracle中如果你要使用hash分區(qū),只需指定分區(qū)的數(shù)量即可。建議分區(qū)的數(shù)量采用2的n次方,這樣可以使得各個(gè)分區(qū)間數(shù)據(jù)分布更加均勻。


    列表分區(qū)(list)

    該分區(qū)的特點(diǎn)是某列的值只有幾個(gè),基于這樣的特點(diǎn)我們可以采用列表分區(qū)。

    List分區(qū)也需要指定列的值,其分區(qū)值必須明確指定,該分區(qū)列只能有一個(gè),不能像range或者h(yuǎn)ash分區(qū)那樣同時(shí)指定多個(gè)列做為分區(qū)依賴列,但它的單個(gè)分區(qū)對應(yīng)值可以是多個(gè)。

    在分區(qū)時(shí)必須確定分區(qū)列可能存在的值,一旦插入的列值不在分區(qū)范圍內(nèi),則插入/更新就會失敗,因此通常建議使用list分區(qū)時(shí),要創(chuàng)建一個(gè)default分區(qū)存儲那些不在指定范圍內(nèi)的記錄,類似range分區(qū)中的maxvalue分區(qū)。

    List分區(qū)時(shí)必須指定的以下內(nèi)容
    分區(qū)方法:list
    分區(qū)列
    分區(qū)描述,每個(gè)描述指定一串文字值(值的列表),它們是分區(qū)列(它們限定將被包括在分區(qū)中的行)的離散值

    比如:
    在根據(jù)某字段,如城市代碼分區(qū)時(shí),可以指定default,把非分區(qū)規(guī)則的數(shù)據(jù),全部放到這個(gè)default分區(qū)。

    create table custaddr (id varchar2(15 byte) not null,areacode varchar2(4 byte) )partition by list (areacode) ( partition t_list025 values ('025'), partition t_list372 values ('372') , partition t_list510 values ('510'),partition p_other values (default))

    栗子1

    CREATE TABLE PROBLEM_TICKETS(PROBLEM_ID NUMBER(7) NOT NULL PRIMARY KEY,DESCRIPTION VARCHAR2(2000),CUSTOMER_ID NUMBER(7) NOT NULL,DATE_ENTERED DATE NOT NULL,STATUS VARCHAR2(20))PARTITION BY LIST (STATUS)(PARTITION PROB_ACTIVE VALUES ('ACTIVE') TABLESPACE PROB_TS01,PARTITION PROB_INACTIVE VALUES ('INACTIVE') TABLESPACE PROB_TS02

    栗子2

    CREATE TABLE ListTable(id INT PRIMARY KEY ,name VARCHAR (20),area VARCHAR (10))PARTITION BY LIST (area)(PARTITION part1 VALUES ('guangdong','beijing') TABLESPACE Part1_tb,PARTITION part2 VALUES ('shanghai','nanjing') TABLESPACE Part2_tb);)

    組合分區(qū)

    如果某表按照某列分區(qū)之后,仍然較大,或者是一些其它的需求,還可以通過分區(qū)內(nèi)再建子分區(qū)的方式將分區(qū)再分區(qū),即組合分區(qū)的方式。

    組合分區(qū)呢在10g中有兩種:range-hash,range-list。

    注意順序,根分區(qū)只能是range分區(qū),子分區(qū)可以是hash分區(qū)或list分區(qū)。

    組合分區(qū)使用range方法分區(qū),在每個(gè)子分區(qū)中使用hash方法進(jìn)行再分區(qū)。

    組合分區(qū)比range分區(qū)更容易管理,充分使用了hash分區(qū)的并行優(yōu)勢。組合分區(qū)支持歷史數(shù)據(jù)和條塊數(shù)據(jù)兩者。

    如添加新的RANGE分區(qū),同時(shí)為DML操作提供更高層的并行性。

    創(chuàng)建組合分區(qū)時(shí),需要指定如下內(nèi)容:

    分區(qū)方法:range
    分區(qū)列
    標(biāo)識分區(qū)邊界的分區(qū)描述
    子分區(qū)方法:hash
    子分區(qū)列
    每個(gè)分區(qū)的子分區(qū)數(shù)量,或子分區(qū)的描述

    范圍-哈希復(fù)合分區(qū)(range-hash)

    這種分區(qū)是基于范圍分區(qū)和散列分區(qū),表首先按某列進(jìn)行范圍分區(qū),然后再按某列進(jìn)行散列分區(qū)。

    create table xiaogongjiang(transaction_id number primary key,item_id number(8) not null,item_description varchar2(300),transaction_date date)partition by range(transaction_date) subpartition by hash(transaction_id) subpartitions 3 store in (xgj_space01,xgj_space02,xgj_space03)(partition part_01 values less than(to_date(‘2006-01-01’,’yyyy-mm-dd’)),partition part_02 values less than(to_date(‘2016-01-01’,’yyyy-mm-dd’)),partition part_03 values less than(maxvalue));

    范圍-列表復(fù)合分區(qū)(range-list)

    這種分區(qū)是基于范圍分區(qū)和列表分區(qū),表首先按某列進(jìn)行范圍分區(qū),然后再按某列進(jìn)行列表分區(qū),分區(qū)之中的分區(qū)被稱為子分區(qū)

    CREATE TABLE SALES(PRODUCT_ID VARCHAR2(5),SALES_DATE DATE,SALES_COST NUMBER(10),STATUS VARCHAR2(20))PARTITION BY RANGE(SALES_DATE) SUBPARTITION BY LIST (STATUS)(PARTITION P1 VALUES LESS THAN(TO_DATE('2003-01-01','YYYY-MM-DD'))TABLESPACE rptfact2009(SUBPARTITION P1SUB1 VALUES ('ACTIVE') TABLESPACE rptfact2009,SUBPARTITION P1SUB2 VALUES ('INACTIVE') TABLESPACE rptfact2009),PARTITION P2 VALUES LESS THAN (TO_DATE('2003-03-01','YYYY-MM-DD')) TABLESPACE rptfact2009(SUBPARTITION P2SUB1 VALUES ('ACTIVE') TABLESPACE rptfact2009,SUBPARTITION P2SUB2 VALUES ('INACTIVE') TABLESPACE rptfact2009))

    Oracle 11g-Interval Partitioning

    數(shù)據(jù)庫管理員日常要做的一件重復(fù)而無聊的工作 比如每隔一天要生成新的24個(gè)分區(qū),用以存儲第二天的數(shù)據(jù)。而在11g中這項(xiàng)工作可以交由Oracle自動完成了,基于Range和List的Interval Partitioning分區(qū)類型登場。

    在 11g 里的 Interval 創(chuàng)建,這種方法對沒有寫全的分區(qū)會自動創(chuàng)建。 比如我
    這里只寫了 1 月日期,如果插入的數(shù)據(jù)有其他月份的,會自動生成對應(yīng)的分區(qū)。

    CREATE TABLE TB_INTERVAL PARTITION BY RANGE (time_col) INTERVAL(NUMTOYMINTERVAL(1, 'month')) (PARTITION P0 VALUES LESS THAN (TO_DATE('1-1-2016', 'dd-mm-yyyy')));

    指定需要Oracle自動創(chuàng)建分區(qū)的間隔時(shí)間,上面這個(gè)例子是1個(gè)月,然后至少創(chuàng)建一個(gè)基本分區(qū),上面這個(gè)例子是在2016-1-1之前的所有數(shù)據(jù)都在P0分區(qū)中,以后每個(gè)月的數(shù)據(jù)都會存放在Oracle自動創(chuàng)建的一個(gè)新分區(qū)中。

    select table_name,partition_name from user_tab_partitions where table_name='TB_INTERVAL'; select count(*) from TB_INTERVAL partition (p1);

    創(chuàng)建按月分區(qū)的分區(qū)表

  • 創(chuàng)建分區(qū)表
  • /* Formatted on 2010/6/10 20:21:12 (QP5 v5.115.810.9015) */ create table intervalpart (c1 number, c3 date) partition by range (c3) interval ( numtoyminterval (1, 'month') ) (partition part1 values less than (to_date ('01/12/2010', 'mm/dd/yyyy')), partition part2 values less than (to_date ('02/12/2010', 'mm/dd/yyyy')) )

    注意: 如果在建 Interval 分區(qū)表是沒有把所有的分區(qū)寫完成,在插入相關(guān)數(shù)據(jù)后會自動生成分區(qū)
    2. 查看現(xiàn)在表的分區(qū):

    SQL> select table_name,partition_name from user_tab_partitions where table_name='INTERVALPART'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ INTERVALPART PART1 INTERVALPART PART2
  • 插入測試數(shù)據(jù):
  • SQL> begin 2 for i in 0 .. 11 loop 3 insert into intervalpart values(i,add_months(to_date('2010-1-1','yyyy-mm-dd'),i)); 4 end loop ; 5 commit; 6 end; 7 /

    PL/SQL 過程已成功完成。
    補(bǔ)充: add_months() 函數(shù)獲取前一個(gè)月或者下一個(gè)月的月份, 參數(shù)中 負(fù)數(shù) 代
    表 往前, 正數(shù) 代表 往后。
    –上一個(gè)月

    select to_char(add_months(trunc(sysdate),-1),'yyyymm') from dual;

    –下一個(gè)月

    select to_char(add_months(trunc(sysdate),1),'yyyymm') from dual;
  • 觀察自動創(chuàng)建的分區(qū):
  • SQL> select table_name,partition_name from user_tab_partitions where table_name='INTERVALPART'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ INTERVALPART PART1 INTERVALPART PART2 INTERVALPART SYS_P22 INTERVALPART SYS_P23 INTERVALPART SYS_P24 INTERVALPART SYS_P25 INTERVALPART SYS_P26 INTERVALPART SYS_P27 INTERVALPART SYS_P28 INTERVALPART SYS_P29 INTERVALPART SYS_P30 INTERVALPART SYS_P31

    已選擇 12 行。
    5. 查看分區(qū)內(nèi)容:

    SQL> select * from INTERVALPART;C1 C3 --------- ---------- 1 2010-01-01 0 2010-01-01 1 2010-02-01 2 2010-03-01 3 2010-04-01 4 2010-05-01 5 2010-06-01 6 2010-07-01 7 2010-08-01 8 2010-09-01 9 2010-10-01 10 2010-11-01 11 2010-12-01 已選擇 13 行。 SQL> select * from INTERVALPART partition(part1); C1 C3 --------- ---------- 1 2010-01-01 0 2010-01-01 SQL> select * from INTERVALPART partition(part2); C1 C3 --------- ---------- 1 2010-02-01

    創(chuàng)建一個(gè)以天為間隔的分區(qū)表

  • 創(chuàng)建分區(qū)表:
  • SQL> create table dave 2 ( 3 id number, 4 dt date 5 ) 6 partition by range (dt) 7 INTERVAL (NUMTODSINTERVAL(1,'day')) 8 ( 9 partition p100101 values less than (to_date('2010-01-01','yyyy-mm-dd')) 10 );
  • 查看表分區(qū):
  • SQL> select table_name,partition_name from user_tab_partitions where table_name='DAVE'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ DAVE P100101
  • 插入測試數(shù)據(jù):
  • SQL> begin 2 for i in 1 .. 12 loop 3 insert into dave values(i,trunc(to_date('2010-1-1','yyyy-mm-dd')+i)); 4 end loop; 5 commit; 6 end; 7 /

    PL/SQL 過程已成功完成。
    4. 觀察自動創(chuàng)建的分區(qū):

    SQL> select table_name,partition_name from user_tab_partitions where table_name='DAVE'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ DAVE P100101 DAVE SYS_P32 DAVE SYS_P33 DAVE SYS_P34 DAVE SYS_P35 DAVE SYS_P36 DAVE SYS_P37 DAVE SYS_P38 DAVE SYS_P39 DAVE SYS_P40 DAVE SYS_P41 DAVE SYS_P42 DAVE SYS_P43

    已選擇 13 行。
    5. 查看分區(qū)內(nèi)容:

    SQL> select * from dave partition(SYS_P32); ID DT ---------- ---------- 1 2010-01-02 SQL> select * from dave partition(SYS_P33); ID DT -------- ---------- 2 2010-01-03 SQL> select * from dave partition(SYS_P34); ID DT -------- ---------- 3 2010-01-04 SQL> select * from dave; ID DT -------- ---------- 1 2010-01-02 2 2010-01-03 3 2010-01-04 4 2010-01-05 5 2010-01-06 6 2010-01-07 7 2010-01-08 8 2010-01-09 9 2010-01-10 10 2010-01-11 11 2010-01-12 12 2010-01-13 已選擇 12 行。

    System Partitioning

    系統(tǒng)分區(qū),在這個(gè)新的類型中,我們不需要指定任何分區(qū)鍵,數(shù)據(jù)會進(jìn)入哪個(gè)分區(qū)完全由應(yīng)用程序決定,實(shí)際上也就是由SQL來決定,終于,我們在Insert語句中可以指定插入哪個(gè)分區(qū)了。
    假設(shè)我們創(chuàng)建了下面這張分區(qū)表,注意,沒有指定任何分區(qū)鍵:

    CREATE TABLE systab (c1 integer, c2 integer) PARTITION BY SYSTEM ( PARTITION p1 TABLESPACE tbs_1, PARTITION p2 TABLESPACE tbs_2, PARTITION p3 TABLESPACE tbs_3, PARTITION p4 TABLESPACE tbs_4 );

    現(xiàn)在由SQL語句來指定插入哪個(gè)分區(qū):
    – 數(shù)據(jù)插入p1分區(qū)

    INSERT INTO systab PARTITION (p1) VALUES (4,5);

    – 數(shù)據(jù)插入第2個(gè)分區(qū),也就是p2分區(qū)

    INSERT INTO systab PARTITION (2) VALUES (7,8);

    – 為了實(shí)現(xiàn)綁定變量,用pno變量來代替實(shí)際分區(qū)號,以避免過度解析

    INSERT INTO systab PARTITION (:pno) VALUES (9,10);

    由于System Partitioning的特殊性,所以很明顯,這種類型的分區(qū)將不支持Partition Split操作,也不支持create table as select操作。

    12C 對表分區(qū)維護(hù)的增強(qiáng)

    Oracle Database 12c對表分區(qū)變化比較多,共分為下面幾點(diǎn)

    1.在線移動分區(qū):通過MOVE ONLINE關(guān)鍵字實(shí)現(xiàn)在線分區(qū)移動。移動過程中,對表和被移動的分區(qū)可以執(zhí)行查詢操作,

    DML語句以及分區(qū)的創(chuàng)建和維護(hù)操作。整個(gè)移動過程對用戶來說是透明的。

    2.多個(gè)分區(qū)同時(shí)操作:可以對多個(gè)分區(qū)同時(shí)進(jìn)行維護(hù)操作,如將一年的12個(gè)分區(qū)合并到一個(gè)新的分區(qū)中,或者將一個(gè)分區(qū)

    分成多個(gè)分區(qū)。可以通過FOR語句指定操作的每個(gè)語句,對于RANGE分區(qū)而言,也可以通過TO來指定處理分區(qū)的范圍。

    多個(gè)分區(qū)操作自動并行完成。

    3.INTERVAL-REFERENCE分區(qū):把11g的interval分區(qū)和reference分區(qū)結(jié)合,這樣主表自動增加一個(gè)分區(qū)后,所有字表,

    孫子表·····重重孫子表上都會自動隨著外界列數(shù)據(jù)增加,自動創(chuàng)建新的分區(qū)。

    4.TRUNCATE和EXCHANGE分區(qū)及子分區(qū)。五分是TRUNCATE還是EXCHANGE分區(qū),在主表上執(zhí)行,都可以級聯(lián)的作用在字表,

    孫子吧·····重重孫子表上同時(shí)執(zhí)行。對于TRUNCATE而言,所有表的TRUNACATE操作在同一個(gè)事務(wù)中,如果中途失敗,
    會回滾到之前的狀態(tài)。通過關(guān)鍵字CASCADE實(shí)現(xiàn)。

    5.異步全局索引維護(hù):對于非常大的分區(qū)表而言,UPDATE GLOBAL INDEX不再是痛苦。Oracle可以實(shí)現(xiàn)了異步維護(hù)的

    功能,即使是幾億條的記錄的全局索引,在分區(qū)維護(hù)操作,比如DROP或TRUNCATE后,仍然是VALID狀態(tài),索引不會失效,

    不過索引的狀態(tài)是包含OBSOLETE數(shù)據(jù),當(dāng)維護(hù)操作完成,索引狀態(tài)恢復(fù)。

    6.部分本地和全局索引:Oracle的所有可以在分區(qū)級別定義。無論全局索引還是本地所有都可以在分區(qū)表的部分分區(qū)

    上建立,其他分區(qū)上則沒有所有。當(dāng)通過所有列訪問全表數(shù)據(jù)時(shí),Oracle通過UNION ALL實(shí)現(xiàn),一部分通過索引掃描,
    另一部分通過全分區(qū)掃描。這可以減少對歷史數(shù)據(jù)的索引量,增強(qiáng)了靈活性。

    具體例子:
    1)添加多個(gè)新分區(qū):

    在12c之前,一次只能添加一個(gè)新分區(qū)到一個(gè)已存在的分區(qū)表。在12c中只需要一條單獨(dú)的ALTER TABLE ADD PARTITION

    命令就可以添加N個(gè)新分區(qū)。

    ALTER TABLE EMP_PART ADD PARTITIONPARTITION P4 VALUES LESS THAN(35000)PARTITION P5 VALUES LESS THAN(40000)

    同樣,只要MAXVALUE分區(qū)不存在,可以添加多個(gè)新分區(qū)到一個(gè)列表和系統(tǒng)分區(qū)表

    2)刪除、截?cái)喽鄠€(gè)分區(qū)/子分區(qū)
    通過在此之前,一次只能刪除/截?cái)嘁粋€(gè)分區(qū)。12c中通過ALTER TABLE table_name {TRUNCAT|DROP} PARTITIONS

    ALTER TABLE EMP_PART DROP PARTITIONS P4,P5;ALTER TABLE EMP_PART TRUNCATE PARTITIONS P4,P5;

    要保持索引更新,使用UPDATE INDEXES或UPDATE GLOBAL INDEXES語句。

    ALTER TABLE EMP_PART DROP PARTITIONS P4,P5 UPDATE GLOBAL INDEXES;ALTER TABLE EMP_PART TRUNCATE PARTITIONS P4,P5 UPDATE GLOBAL INDEXES;

    如果沒有使用UPDATE GLOBAL INDEXES更新索引,也可以通過查詢ORPHANED_ENTRIES字段找出是否有索引包含過期的條目

    3)將單個(gè)分區(qū)分割為多個(gè)新分區(qū)
    在此之前是無法單個(gè)命令完成這個(gè)操作的。

    ALTER TABLE EMP_PART SPLIT PARTITIONS p_max INTO(PARTITION P4 VALUES LESS THAN (30000),PARTITION P5 VALUES LESS THAN(40000),PARTITION P_MAX);

    4)將多個(gè)分區(qū)合并為一個(gè)分區(qū)

    ALTER TABLE EMP_PART MERGE PARTITIONS P2,P3,P4 INTO PARTITION P_MERGE;

    如果是連續(xù)分區(qū),可以通過TO來

    ALTER TABLE EMP_PART MERGE PARTITIONS P2 TO P4 INTO PARTITION P_MERGE;

    普通表轉(zhuǎn)分區(qū)表方法

    將普通表轉(zhuǎn)換成分區(qū)表有 4 種方法:
    1. Export/import method
    2. Insert with a subquery method
    3. Partition exchange method
    4. DBMS_REDEFINITION

    詳情參考
    How to Partition a Non-partitioned Table [ID 1070693.6]
    或者
    oracle將普通表改為分區(qū)表

    表分區(qū)的相關(guān)操作

    1.添加分區(qū)

    添加新的分區(qū)有 2 中情況:
    ( 1)原分區(qū)里邊界是 maxvalue 或者 default。 這種情況下,我們需要把邊界分區(qū) drop 掉,加上新分區(qū)后,在添加上新的分區(qū)。 或者采用 split,對邊界分區(qū)進(jìn)行拆分。
    ( 2)沒有邊界分區(qū)的。 這種情況下,直接添加分區(qū)就可以了。

    以邊界分區(qū)添加新分區(qū)示例:

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

    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 );

    表已創(chuàng)建。

    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 );

    索引已創(chuàng)建。

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

    SQL> insert into custaddr values('1','556'); 已創(chuàng)建 1 行。 SQL> insert into custaddr values('2','551'); 已創(chuàng)建 1 行。 SQL> insert into custaddr values('3','555'); 已創(chuàng)建 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 分區(qū)

    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)添加新分區(qū)

    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 分區(qū)

    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 會自動增加一個(gè)局部分區(qū)索引。驗(yàn)證一下:

    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

    分區(qū)索引自動創(chuàng)建了。

    用 split方法示例

    sql> alter table custaddr split partition p_other values('552') into (partition t_list552 tablespace icd_service, partition p_other tablespace icd_service); 表已更改。

    注意values(‘552’),如果是 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

    注意:分區(qū)表會自動維護(hù)局部分區(qū)索引。全局索引會失效,需要進(jìn)行 rebuild。

    2.刪除分區(qū)

    alter table T_TRACK drop partition p_2005_04;

    3.添加子分區(qū)

    alter table T_TRACKmodify partition P_2005_01add subpartition P_2005_01_P1017 values('P1017');

    4.刪除子分區(qū)

    alter table T_TRACK drop subpartition p_2005_01_p1017;

    5.截?cái)嘁粋€(gè)分區(qū)表中的一個(gè)分區(qū)的數(shù)據(jù):

    alter table sales3 truncate partition sp1--這種方式會使全局分區(qū)索引無效alter table sales3 truncate partition sp1 update indexes--這種方式全局分區(qū)索引不會無效

    說明:
    Truncate 相對 delete 操作很快,數(shù)據(jù)倉庫中的大量數(shù)據(jù)的批量數(shù)據(jù)加載可能
    會有用到; 截?cái)喾謪^(qū)同樣會自動維護(hù)局部分區(qū)索引,同時(shí)會使全局索引 unusable,需要重建

    6.截?cái)喾謪^(qū)表的子分區(qū)

    alter table comp truncate subpartition sub1

    7.截?cái)鄮в屑s束的分區(qū)表

    a、禁用約束alter table sales disable constraint dname_sales1b、截?cái)喾謪^(qū)alter table sales truncate partitoin decc、啟用約束alter table sales enable constraint dname_sales1

    8.查看一個(gè)表是不是分區(qū)表

    select table_name,partitioned from user_tables;TABLE_NAME PAR------------------------------ ---DEPT NODEPT3 YES

    9.將一個(gè)表的分區(qū)從一個(gè)表空間移動到另一個(gè)表空間

    a、查看分區(qū)在哪個(gè)表空間SELECT TABLE_OWNER,TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,SUBPARTITION_COUNTFROM DBA_TAB_PARTITIONS WHERE TABLE_OWNER='SCOTT';b、移動分區(qū)alter table sales move partiton sp1 tablespace tp;c、檢查是否移動成功SELECT TABLE_OWNER,TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,SUBPARTITION_COUNTFROM DBA_TAB_PARTITIONS WHERE TABLE_OWNER='SCOTT';移動表空間后,要重建索引,否則索引會變得無效alter index xxx rebuild

    注意: 分區(qū)移動會自動維護(hù)局部分區(qū)索引, oracle 不會自動維護(hù)全局索引,所以需要我們重新 rebuild 分區(qū)索引,具體需要 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

    10.合并分區(qū):

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

    alter table sales3 merge partitons sp1,sp3 into partition sp3

    合并后的分區(qū)名,不能是邊界值較低的那個(gè)

    11.與分區(qū)表相關(guān)的數(shù)據(jù)字典視圖:

    DBA_TAB_PARTITIONSDBA_IND_PARTITIONSDBA_TAB_SUBPARTITIONSDBA_IND_SUBPARTITIONS

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。