Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2911487
  • 博文数量: 412
  • 博客积分: 3010
  • 博客等级: 中校
  • 技术积分: 7374
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-25 15:15
个人简介

学习是一种信仰。

文章分类

全部博文(412)

文章存档

2014年(108)

2013年(250)

2010年(11)

2009年(43)

我的朋友

分类: Oracle

2013-11-30 20:35:35

第20章  管理分区表和分区索引
使用分区表,将一个大表的数据分布到多个表分区段;使用分区索引,将一个大索引的数据分布到多个索引分区段;
一、建立分区表
执行SQL语句访问分区表时,服务器进程直接访问某个分区表段,而不需要访问整张表的所有数据,从而减少IO,提高系统性能;
Oracle提供了范围分区、散列分区(HASH分区)、列表分区、组合分区四种分区方法:
1、范围分区
例如:sales表年数据1000G,每个季度250G,使用4个分区表段存放四个季度数据,统计季度数据时,只用访问某一个表段即可;
(1)建立范围分区表
指定分区方法(RANGE)、分区列、列值范围;
alter session set nls_date_language=american;
alter session set nls_date_format='dd-mon-yyyy';
CREATE TABLE sales(
        sale_id        NUMBER(10),
        order_id        NUMBER(10),
        customer_id        NUMBER(10),
        sale_amount        NUMBER(10,2),
        sale_date        DATE
)PARTITION BY RANGE(sale_date) (
        PARTITION p1 VALUES LESS THAN ('01-APR-2011') TABLESPACE USER01,
        PARTITION p2 VALUES LESS THAN ('01-JUL-2011') TABLESPACE USER02,
        PARTITION p4 VALUES LESS THAN ('01-OCT-2011') TABLESPACE USER03,
        PARTITION p5 VALUES LESS THAN ('01-JAN-2012') TABLESPACE USER04
);
SQL> select tablespace_name,status from dba_tablespaces;
TABLESPACE_NAME                STATUS
------------------------------ ---------
SYSTEM                         ONLINE
UNDOTBS1                       ONLINE
SYSAUX                         ONLINE
TEMP                           ONLINE
USER01                         ONLINE
USER03                         ONLINE
UNDOTBS                        ONLINE
TEMP01                         ONLINE
TEMP02                         ONLINE
SQL> col name format a50;
SQL> select file#,status,enabled,name from v$datafile;
     FILE# STATUS  ENABLED    NAME
---------- ------- ---------- --------------------------------------------------
         1 SYSTEM  READ WRITE D:\ORACLE_DATABASE\DEMO\SYSTEM01.DBF
         2 ONLINE  READ WRITE D:\ORACLE_DATABASE\DEMO\UNDOTBS1.DBF
         3 ONLINE  READ WRITE D:\ORACLE_DATABASE\DEMO\SYSAUX01.DBF
         4 RECOVER READ WRITE D:\ORACLE_DATABASE\DEMO\USER01.DBF
         5 ONLINE  READ WRITE D:\ORACLE_DATABASE\DEMO\USER02.DBF
         6 RECOVER READ WRITE D:\ORACLE_DATABASE\DEMO\UNDOTBS.DBF
         7 ONLINE  READ WRITE D:\ORACLE_DATABASE\DEMO\USER01_2.DBF
SQL> c/user03 include/user01 including
  1* drop tablespace user01 including contents and datafiles
SQL> r
  1* drop tablespace user01 including contents and datafiles
drop tablespace user01 including contents and datafiles
*
第 1 行出现错误:
ORA-12919: 不能删除默认永久表空间
SQL> alter tablespace user01 online;
alter tablespace user01 online
*
第 1 行出现错误:
ORA-01113: 文件 4 需要介质恢复
ORA-01110: 数据文件 4: 'D:\ORACLE_DATABASE\DEMO\USER01.DBF'
SQL> recover datafile 'D:\ORACLE_DATABASE\DEMO\USER01.DBF';
ORA-00279: 更改 360842 (在 01/04/2012 16:28:45 生成) 对于线程 1 是必需的
ORA-00289: 建议: F:\ORACLE_DATABASE\ARCHIVE\ARC00008_0771675870.001
ORA-00280: 更改 360842 (用于线程 1) 在序列 #8 中
指定日志: {=suggested | filename | AUTO | CANCEL}
已应用的日志。
完成介质恢复。
SQL> alter tablespace user01 online;
表空间已更改。
(2)插入数据
Oracle会根据分区列的列值范围自动把数据插入对应表分区;
SQL> insert into sales values (2011001001,2011000001,2011010001,2502.20,'25-JAN-2011');
已创建 1 行。
SQL> insert into sales values (2011001002,2011000011,2011040001,12502.20,'25-APR-2011');
已创建 1 行。
SQL> insert into sales values (2011001022,2011002011,2011090002,102.20,'21-SEP-2011');
已创建 1 行。
SQL> insert into sales values (2011001022,2011002011,2011120002,102.20,'21-DEC-2011');
已创建 1 行。
(3)查询表所有数据
SQL> select *from sales;
   SALE_ID   ORDER_ID CUSTOMER_ID SALE_AMOUNT SALE_DATE
---------- ---------- ----------- ----------- --------------
2011001001 2011000001  2011010001      2502.2 25-jan-2011
2011001002 2011000011  2011040001     12502.2 25-apr-2011
2011001022 2011002011  2011090002       102.2 21-sep-2011
2011001022 2011002011  2011120002       102.2 21-dec-2011
(4)查询某个分区的数据
SQL> select *from sales PARTITION(p1);
   SALE_ID   ORDER_ID CUSTOMER_ID SALE_AMOUNT SALE_DATE
---------- ---------- ----------- ----------- --------------
2011001001 2011000001  2011010001      2502.2 25-jan-2011
(5)在where条件中引用分区列
Oracle会根据条件列的取值自动扫描特定分区
(6)显示分区段信息
user_segments
2、散列分区(哈希分区)
按照Oracle提供的散列(HASH)函数计算列值数据,根据结算结果分区大表数据;
(1)建立哈希分区表
CREATE TABLE product(
        product_id        number(6),
        description       varchar2(50)
) PARTITION BY HASH(product_id) (
        PARTITION p1 TABLESPACE user01,
        PARTITION p2 TABLESPACE user02,
        PARTITION p3 TABLESPACE user03,
        PARTITION p4 TABLESPACE user04
);
(2)插入数据
Oracle自动根据内置Hash函数计算分区列数据,根据结果分布数据;
insert into product values(1,'pliphs');
insert into product values(2,'totoya');
insert into product values(3,'pliphss');
insert into product values(4,'pSliphs');
insert into product values(5,'pliFphs');
insert into product values(6,'pliSphs');
insert into product values(7,'pliFphs');
insert into product values(8,'pliGphs');
insert into product values(9,'pDSliphs');
insert into product values(10,'pliGGSDphs');
insert into product values(11,'pliGDphs');
insert into product values(12,'plDDiphs');
insert into product values(13,'pliDGHJphs');
(3)查询数据
SQL> select * from product;
SQL> select * from product where product_id=1;
(4)显示分区段信息
user_segments;
3、列表分区
(1)建立列表分区
CREATE TABLE sales_by_region(
        sale_id        number(10),
        address        varchar2(30)
)PARTITION BY LIST(address)(
        PARTITION p1 VALUES ('北京','天津') TABLESPACE user01,
        PARTITION p2 VALUES ('上海','重庆') TABLESPACE user02,
        PARTITION p3 VALUES ('河南','河北') TABLESPACE user03,
        PARTITION p4 VALUES ('广东','香港') TABLESPACE user04
);
4、组合分区
(1)范围、哈希组合分区
(a)建立范围、哈希组合分区表:
假设经常需要按季度统计、且按产品统计;
CREATE TABLE sales_product(
        sale_id        NUMBER(10),
        product_id        NUMBER(10),
        sale_date        DATE
)PARTITION BY RANGE(sale_date) 
         SUBPARTITION BY HASH(product_id) SUBPARTITIONS 4
                STORE IN(user01,user02,user03,user04) (
        PARTITION p1 VALUES LESS THAN ('01-APR-2011') TABLESPACE USER01,
        PARTITION p2 VALUES LESS THAN ('01-JUL-2011') TABLESPACE USER02,
        PARTITION p4 VALUES LESS THAN ('01-OCT-2011') TABLESPACE USER03,
        PARTITION p5 VALUES LESS THAN ('01-JAN-2012') TABLESPACE USER04
);
(b)查看分区信息
SQL> select segment_name,partition_name,tablespace_name from user_segments where segment_name='SALES_PRODUCT';
SEGMENT_NAME                                                                      PARTITION_NAME         TABLESPACE_NAME
--------------------------------------------------------------------------------- ------------------------------ -------
-----------------------
SALES_PRODUCT                                                                     SYS_SUBP21             USER01
SALES_PRODUCT                                                                     SYS_SUBP22             USER01
SALES_PRODUCT                                                                     SYS_SUBP23             USER01
SALES_PRODUCT                                                                     SYS_SUBP24             USER01
SALES_PRODUCT                                                                     SYS_SUBP25             USER02
SALES_PRODUCT                                                                     SYS_SUBP26             USER02
SALES_PRODUCT                                                                     SYS_SUBP27             USER02
SALES_PRODUCT                                                                     SYS_SUBP28             USER02
SALES_PRODUCT                                                                     SYS_SUBP29             USER03
SALES_PRODUCT                                                                     SYS_SUBP30             USER03
SALES_PRODUCT                                                                     SYS_SUBP31             USER03
SALES_PRODUCT                                                                     SYS_SUBP32             USER03
SALES_PRODUCT                                                                     SYS_SUBP33             USER04
SALES_PRODUCT                                                                     SYS_SUBP34             USER04
SALES_PRODUCT                                                                     SYS_SUBP35             USER04
SALES_PRODUCT                                                                     SYS_SUBP36             USER04
已选择16行。
(2)范围、列表组合分区
(a)建立范围、列表组合分区表
假设经常要按季度统计,且按地区统计;
CREATE TABLE sales_region(
        sale_id        number(10),
        sale_date        date,
        address        varchar2(30)
)PARTITION BY RANGE(sale_date) SUBPARTITION BY LIST(address)(
        PARTITION r1 VALUES LESS THAN ('01-APR-2011') TABLESPACE USER01(
                SUBPARTITION r1_1 VALUES('北京','天津'),
                SUBPARTITION r1_2 VALUES('上海','重庆'),
                SUBPARTITION r1_3 VALUES('河南','河北'),
                SUBPARTITION r1_4 VALUES(DEFAULT)
        ),
        PARTITION r2 VALUES LESS THAN ('01-JUL-2011') TABLESPACE USER02(
                SUBPARTITION r2_1 VALUES('北京','天津'),
                SUBPARTITION r2_2 VALUES('上海','重庆'),
                SUBPARTITION r2_3 VALUES('河南','河北'),
                SUBPARTITION r2_4 VALUES(DEFAULT)
        ),
        PARTITION r3 VALUES LESS THAN ('01-OCT-2011') TABLESPACE USER03(
                SUBPARTITION r3_1 VALUES('北京','天津'),
                SUBPARTITION r3_2 VALUES('上海','重庆'),
                SUBPARTITION r3_3 VALUES('河南','河北'),
                SUBPARTITION r3_4 VALUES(DEFAULT)
        ),
        PARTITION r4 VALUES LESS THAN ('01-JAN-2012') TABLESPACE USER04(
                SUBPARTITION r4_1 VALUES('北京','天津'),
                SUBPARTITION r4_2 VALUES('上海','重庆'),
                SUBPARTITION r4_3 VALUES('河南','河北'),
                SUBPARTITION r4_4 VALUES(DEFAULT)
        )
);
(b)查看分区信息        
SQL> select segment_name,partition_name,tablespace_name from user_segments where segment_name='SALES_REGION';
SEGMENT_NAME                                                                      PARTITION_NAME         TABLESPACE_NAME
--------------------------------------------------------------------------------- ------------------------------ -------
-----------------------
SALES_REGION                                                                      R1_1                   USER01
SALES_REGION                                                                      R1_2                   USER01
SALES_REGION                                                                      R1_3                   USER01
SALES_REGION                                                                      R1_4                   USER01
SALES_REGION                                                                      R2_1                   USER02
SALES_REGION                                                                      R2_2                   USER02
SALES_REGION                                                                      R2_3                   USER02
SALES_REGION                                                                      R2_4                   USER02
SALES_REGION                                                                      R3_1                   USER03
SALES_REGION                                                                      R3_2                   USER03
SALES_REGION                                                                      R3_3                   USER03
SALES_REGION                                                                      R3_4                   USER03
SALES_REGION                                                                      R4_1                   USER04
SALES_REGION                                                                      R4_2                   USER04
SALES_REGION                                                                      R4_3                   USER04
SALES_REGION                                                                      R4_4                   USER04
已选择16行。
二、修改分区表
1、增加分区
ALTER TABLE sales ADD PARTITION p5 VALUES LESS THAN('01-APR-2012');
alter table sales SPLIT PARTITION p4 AT('01-08-2011') INTO(PARTITION p4_1,PARTITION p4_2)
SQL> alter table sales_region add partition r5 values less than('01-04-2012');
表已更改。
SQL> alter table sales_region modify partition r5 add subpartition r5_1 values('山东','山西');
alter table sales_region modify partition r5 add subpartition r5_1 values('山东','山西')
            *
第 1 行出现错误:
ORA-14621: 在 DEFAULT 子分区已存在时无法添加子分区
SQL> alter table sales_region add partition r6 values less than('01-08-2012') (subpartition r6_1 values('黑龙江','辽宁','吉林'));
表已更改。
SQL> alter table sales_region modify partition r6 add subpartition r6_2 values('新疆','西藏');
表已更改。
2、删除分区
alter table ... drop partition...
3、截断分区
alter table ... trancate partition ...
4、修改分区名称
alter table ... rename partition ... to ...
5、合并分区
alter table ... merge partition ...,... into partition ...
6、交换分区数据
将分区表某个分区的数据同普通表交换
SQL> create table sale_1 as select * from sales;
表已创建。
SQL> select * from sale_1;
   SALE_ID   ORDER_ID CUSTOMER_ID SALE_AMOUNT SALE_DATE
---------- ---------- ----------- ----------- ----------
2011001001 2011000001  2011010001      2502.2 25-01-2011
2011001002 2011000011  2011040001     12502.2 25-04-2011
2011001022 2011002011  2011090002       102.2 21-09-2011
2011001022 2011002011  2011120002       102.2 21-12-2011
SQL> delete from sale_1 where 1=1;
已删除4行。
SQL> alter table sales exchange partition p1 with table sale_1;
表已更改。
SQL> select * from sale_1;
   SALE_ID   ORDER_ID CUSTOMER_ID SALE_AMOUNT SALE_DATE
---------- ---------- ----------- ----------- ----------
2011001001 2011000001  2011010001      2502.2 25-01-2011
三、建立全局索引和分区索引
1、建立全局索引
SQL> create index gbl_sale_date on sales(sale_date) GLOBAL;
索引已创建。
2、建立分区索引
只能基于分区表建立分区索引,索引数据存放在多个分区段中,且分区个数与分区表个数完全一致;
SQL> create index lcl_sale_date on sales(sale_date) LOCAL;
create index lcl_sale_date on sales(sale_date) LOCAL
                                  *
第 1 行出现错误:
ORA-01408: 此列列表已索引
SQL> drop index gbl_sale_date;
索引已删除。
SQL> create index lcl_sale_date on sales(sale_date) LOCAL;
索引已创建。
四、显示分区表和分区索引相关信息
分区信息:dba_part_tables, all_part_tables, user_part_tables;
表分区:dba_tab_partitions, all_tab_partitions, user_tab_partitions;
子分区:dba_tab_subpartitions, all_tab_subpartitions, user_tab_subpartitions;
分区列:dba_part_key_columns, all_part_key_columns, user_part_key_columns;
子分区列:dba_subpart_key_columns, all_subpart_key_columns, user_subpart_key_columns;
分区索引信息:dba_part_indexs, all_part_indexs, user_part_indexs;
索引分区:dba_ind_parttitions, all_ind_partitions, user_ind_partitions;
索引子分区:dba_ind_subparttitions, all_ind_subpartitions, user_ind_subpartitions;
五、使用OEM管理分区表和分区索引
阅读(1951) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~