zoukankan      html  css  js  c++  java
  • 海量数据库及分区4——《12年资深DBA教你Oracle开发与优化——性能优化部分》

    管理分区
    增加索引分区
    本地索引无法明确的增加分区,其增加只能是基表增加分区,此时新增加的索引分区的名字是Oracle自命名的,但可以给其重新命名。
    也可是使用ALTER INDEX index_name MODIFY DEFAULT ARRTIBUTES  TABLASEPACE tablespace_name修改本地索引分区默认的表空间后,再使用ADD PARTITION增加表的分区,则基表增加分区带来索引分区的增加,会自动将新增加的索引分区指向该表空间。
    接合分区
      分区接合是针对散列分区或者*-散列子分区的,目的是减少分区数。当某个散列分区接合后,Oracle将其分区的数据分散到其它分区中。被接合的分区是由数据库选择的,接合完成后该分区会被删除,且如果没有使用UPDATE INDEX子句,本地索引和全局索引均将变成不可用,一般需要重建索引。
    1.散列分区表的散列分区接合
      使用语法 ALTER TABLE  COALESCE PARTITION。
     
    2.散列子分区表的散列子分区集合
      使用语法 ALTER TABLE MODIFY PARTITION  COALESCE SUBPARTITION。                        参见附件脚本1
     
    删除表分区
      只针对范围和列表分区或者组合*-范围和组合*-列表分区,散列分区不能删除,替代的方式是接合分区。
    分区或子分区删除后,其中的数据也被删除,同样,基于这些分区或者子分区的本地索引中相应的分区和子分区也会被删除;对于全局索引除非使用了UPDATE INDEXS子句,删除分区后其会变成不可用,一般需要重构。如果要防止数据被删除替代的方式是使用合并分区MERGE PARTITION。
    删除分区的语句是ALTER TABLE DROP PARTITION,删除子分区的语句时ALTER TABLE DROP SUBPARTITION。
    1.从包含数据和全局索引的表中删除分区
      此时指的是表中有数据,且包含一个或几个全局索引。
      (1).方法一(推荐的方法)
        先删除分区,再一个个的重构全部索引,此时可以解决范围分区的全局索引的问题(删除后全部变成不可用)。这么做的原因是不要考虑全局索引是什么分区的。一般的方法是编写一个工具子程序,通过动态SQL开重构索引:
      ALTER TABLE table_name DROP PARTITION partition_name;
    ALTER INDEX index_name1_on_ table_name REBUILD;
     
     ALTER INDEX index_namen_on_ table_name REBUILD;
    (2).方法二
        先删除该分区的数据(因为删除数据会重构全局分区),再删除分区,一般针对数据不是特别多的表:
      DELETE FROM table_name PARTITION(partition_name);
    ALTER TABLE table_name  PARTITION partition_name;
    (3).方法三
        使用UPDATE INDEXES子句,此时Oracle会自动重构该全局索引:
         ALTER TABLE table_name  PARTITION partition_name UPDATE INDEXES;
     
    2.从包含数据和参照完整性(外键)的表中删除分区
      (1).方法一
        如果要删除的分区中的数据没有被参照引用,先禁用该参照完整性约束,再删除分区,最后再启用该参照完整性约束。
    (2).方法二
    如果要删除的分区中的数据被参照引用,先删除该分区中数据,再删除分区。
    删除索引分区
    无法显式的删除本地索引的分区,删除的唯一方式是本地索引分区基表的分区被删除时由Oracle自动的隐式删除。
    如果全局索引分区是空的,则可以显式的删除它,使用的语句是ALTER INDEX index_name DROP PARTITION partition_name。但是,如果全局索引分区包含数据,删除则会引起更高级的分区(即下一个分区)变得不可用。如果非要这么做,则对更高级的分区需要重构,语法是:
     ALTER INDEX index_name REUBILT PARTITION nextpartition_name
      
    交换分区
     
       可以将一个分区(子分区)和非分区表进行数据交换,oracle交换的方法是其实是对逻辑存储段进行交换。同样,散列|范围|列表分区可以与复合*-散列|*-范围|*-列表分区间也可以进行数据交换。当应用中需要将非分区表的数据转换进入分区表的分区时非常高效实用。使用INCLUDEING INDEXES子句可以同步将本地索引也进行交换,使用WITH VALIDATATION子句还可以实现行数据的验证。
    交换分区时如果不带UPDATE INDEXES子句,则全局索引或全局索引基于的分区将变为不可用。
    1.三种单级分区与非分区表的交换
    使用ALTER TABLE table_name EXCHANGE PARTITION partition_name WITH TABLE nonpartition_name
    交换前:
     
    1.三种单级分区与非分区表的交换
    交换后:
    如再次交换,则二者的数据会再次互换,变成第一次交换前的状态
     
    2. 单级散列分区表与复合*-散列分区的交换
    此时要求单级散列分区表的分区键与复合*-散列分区表的子分区键相同,且两个交换的散列分区数也得相同,此外也不能指定单级散列分区表的某一个分区进行交换。
    交换前:
     
     
    2. 单级散列分区表与复合*-散列分区的交换
    交换后:
     
    再交换后,回到原始状态:
     
    参见附件脚本3
     
     
    3. 复合*-散列分区中的散列子分区交换
       使用ALTER TABLE ... EXCHANGE SUBPARTITION与非分区表进行交换,且只能跟非分区表进行交换。 参见附件脚本4
    交换前:
     
    交换后:
     
     
    4.单级列表分区表与复合*-列表分区的交换
       此时要求List分区表的分区键和*-List表的子分区键相匹配,前者的List分区数与后者的List子分区相同。 参见附件脚本5
    5. 复合*-列表分区中的列表子分区交换
    同样也是使用ALTER TABLE ... EXCHANGE SUBPARTITION与非分区表进行交换,且只能跟非分区表进行交换。 参见附件脚本6
    6.单级范围分区表与复合*-范围分区的交换
    此时要求Range分区表的分区键和*-Range表的子分区键相匹配,前者的Range分区数与后者的Range子分区相同。 参见附件脚本7
    7. 复合*-范围分区中的范围子分区交换
        同样也是使用ALTER TABLE ... EXCHANGE SUBPARTITION与非分区表进行交换,且只能跟非分区表进行交换。 参见附件脚本
    列表分区值的增加 
    仅有列表分区或列表子分区存在该功能,如果要增加的值在其它分区或者当前分区的其它子分区中存在,则不能增加,因此对于存在default的List分区/子分区,本功能不可用。本操作完成后,本地索引和全局索引保留为可用。 见附件脚本9 
    1.列表分区
     ALTER TABLE table_name MODIFY PARTITION partition_name
     ADD VALUES
    2.列表子分区
    ALTER TABLE table_name MODIFY SUBPARTITION subpartition_name
     ADD VALUES
     
    列表分区值的删除
     
    也是仅有列表分区或列表子分区存在该功能,如果要删除的值在当前分区子分区中存在,则不能报错,必须先删除该值对应的记录才能再删除,如果一个分区中只有一个值,无论其有否数据,也不能删除该值,因此对于存在default的List分区/子分区,本功能不可用。本操作完成后,本地索引和全局索引保留为可用。 参见附件脚本10
    1.列表分区
     ALTER TABLE table_name MODIFY PARTITION partition_name
     DROP VALUES
    2.列表子分区
    ALTER TABLE table_name MODIFY SUBPARTITION subpartition_name
     DROP VALUES
     
    移动分区
    移动分区的作用包括:
     
    l重新聚合数据,以减少碎片
    l将分区移动到另外一个表空间(MODIFY命令搞不定)
    l修改“建立时间”属性
    l对有压缩属性的,将数据压缩后存储,因此对压缩分区表分写入后需要调用本命令
     
    一般来说,该命令执行完后,本地索引和全局索引变成不可用,需要重新构建。
    1.移动表分区
     ALTER TABLE table_name MOVE PARTITION partition_name
     [TABLESPACE new_tablespace_name][NOLOGGING|LOGGING][COMPRESS]
     
    1.移动表分区
     ALTER TABLE table_name MOVE PARTITION partition_name
     [TABLESPACE new_tablespace_name][NOLOGGING|LOGGING][COMPRESS];
    执行该命令后,即使没有指定新的表空间,也会删除旧的分区段,创建一个新的分区段。
    2.移动子分区
    针对复合分区表,同上,关键字改成SUBPARTIOTION  subpartition_name,此外此时只能移动子分区,对分区的移动是非法的。
    3.移动索引分区
    切记不要通过MOVE指令来执行,虽然Oracle支持,建议一律先删除索引再重建。
    参见附件脚本11
     
     
     
    重构索引分区
    重构索引分区的理由一般包括:
    l恢复空间或改善性能
    l修复因介质原因而损坏的索引分区
    l通过SQL*Loader或导入工具装载数据后重构本地索引
    l重构被标记为UNUSABLE的索引分区
    l启用b-tree索引中的键压缩
    1.重构全局索引分区
    有以下两种方法:
    (1).ALTER INDEX index_name REBUILD PARTITION partition_name
      (2).删除索引,再重建。推荐这种方法
      参见附件脚本12.1
     
     
    2.重构本地索引分区  参见附件脚本12.2
    有以下两种方法:
    (1).ALTER INDEX index_name  REBUILD
           {PARTITION partition_name| SUBPARTITION subpartition_name}
      (2). ALTER TABLE table_name  MODIFY
           [{PARTITION partition_name| SUBPARTITION subpartition_name}
           REBUILD UNUSABLE LOCAL INDEXES
           
    重命名分区
     
    使用重命名分区有两种需求,一种是将分区名改成更有意义的,第二种是将系统自动生成的分区名改成自己想要的名字。
    1.重命名分区/子分区
      ALTER TABLE table_name RENAME PARTITION old_name TO new_name;
      ALTER TABLE table_name RENAME SUBPARTITION old_name TO new_name;
    2.重索引分区
      除关键字改成ALTER TABLE table_name 改成ALTER INDEX index_name外,其它同重命名分区/子分区
     
     
    参见附件脚本13
     
     
    拆分分区
     
    当一个分区变得很大时会带来备份、恢复和维护操作的长时性,此时可以对分区进行拆分,拆分可以将一个分区拆分成两个,拆分的分区如果包含数据,完成拆分后索引会变得不可用,一般需要重构。
    1.拆分Range分区表的Range分区
      ALTER TABLE table_name SPLIT PARTITION partition_name
      AT(values) INTO(PARTITION new_ partition_name1,                   
                      PARTITION new_partition_name2);
      其中拆分完分区后的第一个分区的值小于AT值,第二个小于原来分区的值。如果拆分完的分区没有指定名字,系统使用SYS_Pn自动命名。拆分完成后如果存在索引,还需要重构。
    参见附件脚本14.1
     
    2.拆分List分区表的List分区
      ALTER TABLE table_name SPLIT PARTITION partition_name
      VALUES(values) INTO(PARTITION new_ partition_name1,                   
                      PARTITION new_partition_name2);
      其中values值是定义中枚举值范围的子集,该值写入到拆分后的第一个分区,未包含的写入到第二个分区。也可以对default分区进行拆分,方法同上。
     
    参见附件脚本14.2
     
    3.拆分*-hash分区表的的分区
     
    子分区可以采用SUBPARTITIONS n方式,也可以采用PARTITION partition_name方式。如果不指定SUBPARTITION子句,则从父分区去继承子分区数。需要注意的是拆分时继承的属性与合并时不同,合并时继承的是表级的属性,原因是合并时有两个父分区。其中关键字values或at取决于分区的类型,即range为at,list为values
    参见附件14.3
     
     
    4.拆分*-List分区表的分区
      此时分区级和子分区级均可拆分
    (1).拆分*-List分区
    如果是R-L类型,则与拆分范围分区类似,如果是L-L类型,则跟拆分列表分区类似。无需指定子分区语句,子分区属性从拆分的父分区处继承,此时拆分后新子分区的名字无法指定。
    (2).拆分*-List子分区
      ALTER TABLE table_name SPLIT SUBPARTITION subpartition_name
      VALUES(values) INTO(SUBPARTITION new_subpartition_name1,                   
                      SUBPARTITION new_subpartition_name2);
    参见附件脚本14.4
     
     
    5.拆分*-Range分区表的分区   参见附件脚本14.5
      此时也是分区级和子分区级均可拆分,新分区的子分区的范围值不可指定,新分区的子分区属性继承自父分区。
    (1).拆分*-Range分区
    如果是R-R类型,则与拆分范围分区类似,如果是L-R类型,则跟拆分列表分区类似。无需指定子分区语句,子分区属性从拆分的父分区处继承,此时拆分后新子分区的名字无法指定。
    (2).拆分*-Range子分区
      ALTER TABLE table_name SPLIT SUBPARTITION subpartition_name
      AT(values) INTO(SUBPARTITION new_subpartition_name1,                   
                      SUBPARTITION new_subpartition_name2);
     
     
    6.拆分索引分区
      本地索引分区无法显式的拆分,其拆分的唯一途径是基表的分区拆分时由Oracle隐式的进行拆分。
    全局索引分区可以拆分,拆分完成后需要重构,但我们不推荐这么做,如下例:
    ALTER INDEX quon1 SPLIT
    PARTITION canada AT ( 100 ) INTO
    PARTITION canada1 ...,
    PARTITION canada2 ...);
    ALTER INDEX quon1 REBUILD PARTITION canada1;
    ALTER INDEX quon1 REBUILD PARTITION canada2;
     
     
    清空分区
     
       使用ALTER TABLE table_name TRUNCATE {PARTITION partition_name| SUBPARTITION subpartition_name}清空分区会清除掉分区中的数据,类似清空表。但是索引分区不可清空,清空分区同步会清空索引分区在该分区的数据。
    1.清空表分区
    会清空分区数据,但不会回收空间,有两种情况:
    (1).包含数据和全局索引的分区
      方法一是先清空该分区再重构基于该分区的全局索引;第二种方法是先删除该分区的数据再清空该分区;第三种方法是使用UPDATE INDEXES子句。推荐第二种方式。
     
     
    1.清空表分区
    (2).包含数据和代参考完整性约束的分区
      方法一先禁用该约束再清空分区最后启用该约束;第二种方法是先删除该分区的数据再清空该分区。推荐第一种方式。
    2.清空子分区
    直接使用该语句,同步的本地索引数据也会删除。
     
     
     
    相关数据字典
    视图
    说明
    视图
    说明
    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_COL_STATISTICS
    ALL_PART_COL_STATISTICS
    USER_PART_COL_STATISTICS
    分区的列和柱状图统计信息
     
     
    视图
    说明
    视图
    说明
    DBA_SUBPART_COL_STATISTICS
    ALL_SUBPART_COL_STATISTICS
    USER_SUBPART_COL_STATISTICS
    子分区的列和柱状图统计信息
    DBA_PART_HISTOGRAMS
    ALL_PART_HISTOGRAMS
    USER_PART_HISTOGRAMS
    分区柱状图数据
    DBA_SUBPART_HISTOGRAMS
    ALL_SUBPART_HISTOGRAMS
    USER_SUBPART_HISTOGRAMS
    子分区柱状图数据
    DBA_PART_INDEXES
    ALL_PART_INDEXES
    USER_PART_INDEXES
    分区索引
     
     
    按范围分区和列表分区
     
    1.按范围分区
    l大表且对数据的扫描经常按使用范围时,如日期和时间
    l对数据的维护需要使用滚动窗口时,如在数据仓库中,经常按月度需要装载最近3年(36个月)的数据。滚动窗口是指一般是周期性的需要装载新数据并清除旧数据的时间窗口
    2.列表分区
    l列的取值范围是离散且可以枚举时,如按地理区域分区、按流程状态分区
    散列分区
       无明确的按范围或者列表方式分区时,可考虑在以下情况下使用散列分区:
     
    l想要数据均衡分布,并可启用部分/全部分区智能连接功能时
    l分区键作为主要的唯一值或者值列表时,如使用序列为主键
    l想要数据随机均衡分布在不同的分区以便规避I/O瓶颈时
     
    当一个列或多个列构成唯一值时,使用这些列为分区键来建立散列分区,并且将分区数尽量设置为2的幂,如2、4、8、16、32等,一般会获得比较好的性能。
     
    1.复合范围-范围分区
     
    l两个均能按范围分区的维度时,如两个维度的时间(如起始时间、截止时间)
     
    2.复合范围-散列分区
     
    l存储有大量历史数据,且这些历史数据经常要跟另外一个大表连接时。如销售历史表和客户表一期关联对比分析趋势数据时
    l传统意义上的散列分区数据经常需要滚动操作时,如某个系统访问的日志信息,需要统计不同客户端ip各个时期的各种记录(如访问记录次数、在线时长等)时
     
     
    3.复合列表-范围分区
     
    l一般用在第一个维度是枚举值,第二个维度是范围值时,如捐赠数额表,可以先按币种列表分区,再按金额范围分区
     
    4.复合列表-散列分区
     
    l通常用在第一个维度是枚举值,第二个维度无法按范围或列表分区时,如某个信用卡记录表,可以先按区域列表分区、再按卡号进行散列分区
     
     
    5.复合列表-列表分区 
    l一般用两个维度都是不连续的离散值时,如前述信用卡账户表,可以先按区域列表分区,再按省份或账户类型(白金卡、金卡、银卡、普通卡等)列表分区
     
    习题
    1.本地分区索引的分区可以增加吗,为什么?
    2.散列分区要减少分区数如何处理?范围分区和列表分区呢?请试着举例说明。
    3.假定表A基于列colA有3个范围单击分区,且建立了一个全局分区索引,表中有数据,如果要删除某个分区,有几种方法?
    4.本地索引分区可以删除吗,为什么?如果某个表存在全局分区索引,删除某个分区后,需要接下来执行什么操作,为什么?
    5.单级散列分区表与复合*-散列分区交换时,需要满足什么条件?
    6.举例说明复合*-散列分区中的散列子分区交换为什么只能跟非分区表进行交换。
    7.对分区执行移动操作的两大主要目的是什么?
    8.列表归纳各种分区的拆分限制条件,并举例说明其语法。
    9.散列分区、范围分区、*-Hash和*-List分区分别建议在什么情况下使用?
    10.练习本课程的分区管理操作,增强对分区管理的直观理解。
     
  • 相关阅读:
    Linux系统安装
    设计模式的原则
    vue基础
    软考常考题目及解题技巧
    软件设计师
    Wireshark 使用教程
    JVM 调优
    Shell脚本编写
    Linux相关知识
    HTTP缓存机制及原理
  • 原文地址:https://www.cnblogs.com/liuzhuqing/p/7480622.html
Copyright © 2011-2022 走看看