zoukankan      html  css  js  c++  java
  • Oracle-表分区

    使用分区技术的有点:

    1.减少维护工作量,独立管理每个分区比管理单个大表要轻松得多

    2.增强数据库的可用性,当一个表的一个或几个分区由于系统故障而不能使用,而其余的分区仍然可以用;如果系统故障只影响表的一部分分区,那么,只有这部分分区需要修复,这就比修复整个大表耗费的时间少许多

    3.均衡I/O,减少竞争,通过把表的不同分区分配到不同的磁盘来平衡I/O改善性能

    4.分区对用户保持透明,最终用户感觉不到分区的存在

    5.提高查询速度:对大表的查询、增加、修改等操作可以分解到表的不同分区中来并行执行,这样就可以加快运行速度,在数据仓库的TP查询特别有用

    Oracle 11g相对于其他低版本的Oracle在分区方面增加了很多功能如:

    引入扩展的分区功能

    Interval分区

    外键分区

    虚拟列分区

    引入了分区建议器

    创建分区

    A--范围分区

      关键字“RANGE”,创建分区后,其中的数据可以根据分区键值指定的范围进行分布,当数据在范围内均匀分时时,性能最好。

    如:创建一个商品零售表,然后为该表按照销售日期所在的季度创建4个分区:

    create table ware_retail_part(
    id integer primary key,
    retail_date date,
    ware_name varchar2(50))
    partition by range(retail_date)
    (
    --2011年第一季度为part_01分区
    partition par_01 values less than(to_date('2011-04-01','yyyy-mm-dd'))tablespace play,

    --2011年第二季度为part_02分区
    partition par_02 values less than(to_date('2011-07-01','yyyy-mm-dd'))tablespace play,

    --2011年第三季度为part_03分区
    partition par_03 values less than(to_date('2011-10-01','yyyy-mm-dd'))tablespace users,

    --2011年第四季度为part_04分区
    partition par_04 values less than(to_date('2012-01-01','yyyy-mm-dd'))tablespace users
    )
    /

    插入若干条记录后

    查询数据表ware_retail_part中分区par_02的全部记录

    select * from ware_retail_part partition(par_02);

    用户通过分区表(分了区的数据表)来查询数据,这种查询速度比从整个表中查询快得多

    另外,range分区的字段可以是两个或多个:

    如:创建一个商品零售表,然后为该表按照销售编号和销售日期组合创建3个分区:

    create table ware_retail_part2
    (
    id integer primary key,
    retail_date date,
    ware_name varchar2(50)
    )
    partition by range(id,retail_date)
    (
    partition par_01 values less than(10000,to_date('2011-12-01','yyyy-mm-dd'))tablespace play,
    partition par_02 values less than(20000,to_date('2012-12-01','yyyy-mm-dd')) tablespace play,
    partition par_03 values less than(maxvalue,maxvalue) tablespace users)
    /

    B--散列分区

      HASH分区,在列的取值难以确定的情况下采用的分区方法

    对于像身份证号码这种数据散列分区特别有效,其他如范围查询和不等式查询则起不到什么优化作用

    如:创建一个商品零售表,然后将该表id列的值根据自身情况散列地存放在指定的两个表空间中:

    create table ware_retail_part3(

    id integer primary key,

    retail_date date,

    ware_name varchar2(50)

    )

    partition by hash(id)

    (

    partition par_01 tablespace play,

    partition par_02 tablespace users

    );

    然后插入数据

    插入的记录到底被分配到哪个分区,用户是无法直接判断的,这是由Oracle系统通过计算id的hash值,然后系统会按照均匀分布的原则自动分配的

    所以只能尝试是在partition par_01 还是在partition par_02中

    当然,Oracle 11g可以实现自动分配分区名

    如:首先创建一个表person,然后为该表创建HASH列(id)分区,要求创建的两个分区由系统自动生成分区名,并分别放置在表空间play,users:

    create table person
    (
    id number primary key,
    name varchar2(20),
    sex varchar2(2)
    )
    partition by hash(id)
    partitions 2
    store in(play,users)
    /

    另外在,创建HASH分区表时,用户还可以指定所有分区的初始分配空间大小:

    如:首先创建一个表Goods,然后为该表创建HASH列分区,要求为创建的表分区指定初始化空间,大小为2048KB

    create table goods
    (
    id number,
    goodname varchar2(50)
    )
    storage(initial 2048k)
    partition by hash(id)
    (
    partition par1 tablespace play,
    partition par2 tablespace users
    )
    /

    C--列表分区

      关键字是LIST,如果表的某个列的值可以枚举,则可以考虑对表进行列表分区。比如客户表clients那么就可以按照客户所在的省份进行分区

    如:首先创建一个用于保存客户信息的表clients,然后以province列为分区键创建列表分区

    create table clients
    (
    id integer primary key,
    name varchar2(50),
    province varchar2(20)
    )
    partition by list(province)
    (
    partition shandong values('山东省'),
    partition guangdong  values('广东省'),
    partition yunnan values('云南省')
    )
    /

    插入数据后,即可按照所有地区查询

    D--组合分区

      结合两个数据分区的方法可以成为一个组合分区方法。首先用第一个数据分布方法对表格进行分区,然后再用第二个数据分区方法对每个分区进行二次分区

      目前的Oracle仅支持对索引组织表(索引和数据一起的表格)进行范围分区,列表分区或散列分区,但不支持对其进行组合分区。

    如:首先创建一个保存人员信息的数据表person2,然后创建3个范围分区,每个范围分区又包含2个子分区,子分区没有名字,由系统自动生成,并要求将其分布在2个指定的表空间中:

    create table person2
    (
    id number primary key,
    name varchar2(20),
    sex varchar2(2)
    )
    partition by range(id)
    subpartition by hash(name)
    subpartitions 2 store in(play,users)
    (
    partition par1 values less than(5000),
    partition par2 values less than(10000),
    partition par3 values less than(maxvalue)
    )
    /

      该分区首先按照范围进行分区,然后对子分区按照HASH进行分区,根据name列的hash值确定该行分布在paly和users某个表空间上

    E--Interval分区

      Oracle 11g 新引入的分区方法,是范围分区的一种增强功能,可以实现equi_sized范围分区的自动化。创建的分区作为元数据,只有最开始的分区是永久分区。随着数据的增加会分配更多的部分,并且自动创建新的分区和本地索引

     如:首先创建一个表salerecord,然后为该表创建interval分区:

    create table salerecord
    (
    id number primary key,
    goodsname varchar2(50),
    saledate date,
    quantity number
    )
    partition by range(saledate)
    interval(numtoyminterval(1,'year')) --interval分区实现按年份进行自动分区
    (
    partition par_first values less than(to_date('2012-01-01','yyyy-mm-dd'))
    )
    /

     函数:numtoyminterval()功能是将数字转换成interval year to month 

    进行interval分区的表格有传统的范围部分和自动生成的interval部分。对于已经进行了范围分区的表格,可以通过alter table ...set interval选项扩展为interval分区的表格

    表分区策略

      对表进行分区时,首先考虑和分析分区表中每个分区的数据量,其次要为每个分区创建相应的表空间

    1.识别大表

      一般来说,数据占用存储空间大的表就是大表,系统架构师要做到的就是如何确定哪些表属于大表。如果要在目前运行的系统上进行表数据量分析,那么主要采用analyze table进行分析,然后查询DD获得相应的数据量;如果是一个正在进行需求分析的表,只能采用估计的方法了

    2.大表如何分区

      大表可以按时间分区。比如,如果按照月份分区,则需要为每个月创建一个数据表空间;如果按照季度分区,则一年要创建4个表空间;如果要创建5年用的表空间,则需要创建20个表空间

    3.分区的表空间规划

      分区方法确定后,就要着手创建表空间,创建表空间前要对每个表空间的大小进行估算,原则是,往后增长幅度在20%-30%

    管理表分区

      

    1.添加表分区

      对于已经存在表分区的某个表,如果要添加一个新的表分区,通常使用alter table ...add partition

    如:在客户信息表clients中,添加一个省份为“河北省”的表分区:

    alter table clients
    add partition hebei values('河北省')
    storage(initial 10k next 20k) tablespace play
    nologging
    /

      不仅可以增加分区,也可以给增加的分区指定存储属性

    2.合并分区

       可以减少散列分区或者复合分区的个数。在合并分区之后,Oracle系统将做以下处理:

    A-:在合并分区时,HASH列函数将分区的内容分布到一个或多个保留分区中

    B-:原来内容所在的分区完全被清除

    C-:与分区对应的索引也被清除

    D-:将一个或多个索引的本地索引分区标识为不可用(UNSABLE)

    E-:需要对不可用的索引进行重建

      (1)合并散列分区

    如:合并person分区表中的一个HASH分区:

    alter table person coalesce partition;

      (2)合并复合分区

    如:把person2分区表中的part3分区合并到其他保留子分区中:

    alter table person2 modify partition par3 coalesce subpartition;

    3.删除分区

      可以从范围分区或复合分区中删除分区。但是散列分区和复合分区的散列子分区,只能通过合并来达到删除的目的

      (1)删除一个表分区

    如:把ware_retail_part分区表中的par_04分区删除

    alter table ware_retail_part drop partition par_04;

      (2)删除有数据和全局索引的表分区

     如果分区中包含了数据,并且在表中定义了一个或者多个全局索引,可以使用alter table...drop partition 语句删除表分区,这样可以保留全局索引,但是索引会被标识为不可用(unusable),因而需要重建索引

    如:删除ware_retail_part 分区表中的par_04分区,然后重建索引ware_index:

    alter table ware_retail_part drop partition par_04;

    alter index ware_index rebuild;

      (3)使用delete和alter table..drop partition语句

    在执行drop partition语句前,要首先执行delete语句来删除分区的所有数据行,然后执行alter table...drop partition,但是执行delete语句时,需要更新全局索引

    如:首先删除ware_ratail_part 分区表总第四季度的数据,然后再删除第四季度数据对应的par_04分区

    delete from ware_retail_part where retail_date>= to_date('2011-10-01',yyyy-mm-dd);

    alter table ware_retail_part drop partition par_04;

      (4)删除具有完整性约束的分区

    如果分区具有完整性约束,可以采用下面方法:

    法一:首先禁止完整性约束,然后执行alter table...drop partition  ,最后激活约束

    如:首先禁用books_1 表的主键约束 BOOK_PK,然后删除 books_1表的part_01,最后激活books_1表的主键约束BOOK_PK

    alter table books_1 disable constraints BOOK_PK;

    alter table books_1 drop partition part_01;

    alter table books_1 endable constraints BOOK_PK;

    法二:

    首先执行delete删除分区中的行,然后用alter table..dorp partition

    如:首先删除books_1表中part_01分区中的所有记录,然后再删除part_01分区:

    delete from books_1 where bookno<1000;

    alter table books_1 drop partition part_01;

    并入分区

      用户使用merge partition将相邻的范围分区合并在一起变为一个新的分区,需要注意,该分区继承原来两个分区的边界;原来的两个分区与相应的索引一起被删除;如果被合并的分区非空,则该分区被标识为unusable;不能对hash分区表执行merge partition语句

      并入范围分区是将两个以上的分区合并到一个存在的分区中,合并后一般索引要重建。

    如:首先在sales表中创建4个分区,然后再将第3个分区并入到第4个分区中:

    create table sales
    (
    id number primary key,
    goodsname varchar2(10),
    saledate date
    )
    partition by range(saledate)
    (
    partition part_sea1 values less than(to_date('2011-04-01','yyyy-mm-dd')) tablespace play,
    partition part_sea2 values less than(to_date('2011-07-01','yyyy-mm-dd')) tablespace users,
    partition part_sea3 values less than(to_date('2011-10-01','yyyy-mm-dd'))tablespace play,
    partition part_sea4 values less than(to_date('2012-01-01','yyyy-mm-dd')) tablespace users
    )
    /

    在sales表中创建局部索引

    create index index_3_4 on sales(saledate)
    local(
    partition part_sea1 tablespace play,
    partition part_sea2 tablespace users,
    partition part_sea3 tablespace play,
    partition part_sea4 tablespace users
    )
    /

    使用alter table...merge partition 把第3个分区并入到第4个分区中:

    alter table sales merge partitons part_sea3,part_sea4  into partition part_sea4;

    最后重建局部索引

    alter table sales modify partition part_sea4 rebuild unusable local indexes;

  • 相关阅读:
    JAVA多线程大总结篇
    JAVA多线程总结01
    Eclipse配置Tomcat
    jdbc注册驱动出现Loading class `com.mysql.jdbc.Driver'. This is deprecated的问题:
    windows10环境下eclipse连接mysql
    mysql忘记密码,如何修改
    c++笔记:虚函数必要但易忘的一些性质
    Mysql 4 —— select 进阶
    Mysql 3 —— 建表
    数据结构实验一:单链表就地翻转
  • 原文地址:https://www.cnblogs.com/xcnblog3035/p/5256203.html
Copyright © 2011-2022 走看看