Loading
0

Oracle数据库分区技术概览

 

Oracle数据库的分区技术强化了各种应用的性能、可管理性和可用性,并且有助于减少存放大量数据的总成本。分区允许表、索引和索引组织表可以被细分到更小的片中,使得这些数据库对象能够细粒度的被管理和访问。Oracle提供了丰富多样的分区策略和扩展能力去应对每种业务要求。因为它是完全透明的,所以分区可以被实施到几乎任何的应用上而且不需要修改应用,所以没有潜在的昂贵的修改应用而造成的耗时。

分区技术将表、索引或者索引组织表分割成更小的片,这个数据库对象的每个片被称为一个分区。每个分区有它自己的名称,并且可以选择有它自己的存储特性。

分区的基础知识

从一个数据库管理员的角度来说,一个分了区的对象有多个片可以被统一管理或者独立管理。这给予了一个管理者管理分了区的对象相当大的灵活度。然而,从应用的角度来说分了区的表与没有分区的表是没有不同的,访问一个分区表示用的SQL查询和DML语句没有修改的必要。

下图展现了分区表与非分区表的区别:

vldbg008

 

分区键

分区表中的每一行数据被明确的分配到一个单独的分区中,分区键由一个或多个字段组成,它决定了每行数据存储的分区。Oracle通过分区键会自动的引导insert、update和delete操作到适合的分区。

 

分区表

任何表都能被分区到百万个分离的分区中,除了那些包含了LONG或者LONG RAW数据类型字段的表,你可以使用包含了CLOB或者BLOB数据类型字段的表。

 

什么情况下选择将表分区?

满足以下一些情况可以考虑将表分区:

  • 一般情况下表的大小是否超过2GB总是被定位考虑是否要分区的基准。
  • 具有历史数据的表,新的数据插入到最新的分区中。一个典型的例子就是一张历史表只有当前一个月的数据是可更新的,而其他11个月的数据是只读的。
  • 当表的内容必须被分布放置到不同类型的存储设备上时应该考虑分区。

 

什么情况下选择将索引分区?

满足以下一些情况可以考虑将索引分区:

  • 当数据被删除时为了避免重建整个索引。
  • 执行部分数据维护操作时不能出现整个索引无效。
  • 降低由于在索引上有一个值单调递增的字段而引起的索引歪斜。

 

分区的索引组织表

将索引组织表分区对于改善索引组织表的性能、管理能力和可用性是很有用的。

对于分区索引组织表:

  • 分区字段必须是主键字段的子集
  • 二级索引能够被分区(包括本地的和全局的)
  • 溢出数据段总是与表分区均分

 

系统分区

系统分区可以使应用控制分区而没有不需要数据库控制数据的放置。在没有已知的可用的特定分区的情况下,数据库简单的提供了中断表进入分区的能力。分区的所有切面都不得不由应用来控制。例如,试图插入一个系统分区的表时没有明确指明一个分区,那么这个操作将会失败。

系统分区提供了众所周知的优点(扩展性、可用性、管理能力),但是分区和实际数据的放置是需要应用来控制的。

 

分区的信息生命周期管理

信息生命周期管理是关注它的生命周期里的管理数据。分区在信息生命周期管理中起着关键作用,因为它可以使数据组(分区)在不同类型的存储设备上分布存放并且可独立管理。

 

分区和LOB数据

数据库中存储在LOB字段上的非结构化数据(比如图片和文档)也能够被分区。当一个表被分区时,所有的字段被放在这个分区的表空间上,除了LOB字段,它可以放在自己的表空间上。

对于有大LOBs字段的表这个技术是非常有用的,因为他们能够与主数据分离存放。对于主数据经常更新而LOB数据不常更新的表来说是很有用的。例如,一条employee记录也许包含了一张照片,这不会经常更改,然而employee得个人详细信息(比如地址、部门、经理等等)是会修改的。这就意味着相对便宜的存储可以用来存放LOB数据,而更贵的、更快的存储可以用来存储employee的其他数据。

 

Collections in XMLType and Object Data

对于使用了XMLTpye或者Object表或者拥有这些类型字段的表,分区技术提供了标准的分区好处,诸如可以使表和索引分割成更小的片,因此能够使这些数据库对象能够在一个细粒度下进行管理和访问。

当你对一个XMLTpye表或者拥有一个XMLType字段的表示用了list、range或者hash分区的时候,默认情况下任何带有数据的ordered collection tables有序集合表(OCTs)都将按照规则自动被分区。这种均匀分区意味着一个OCT的分区方式是跟随他的父表或者说基表的分区方式的。对于基表的每一个分区都有一个对应的集合表分区。子元素存储在对应其父元素所在的基表分区的集合表分区中。

如果你要对一个拥有嵌套表的表进行分区,那么Oracle数据库会使用原始的基础表的分区模式作为基准来对嵌套表进行分区。这种按照一个基表分区模式对于每个嵌套表进行分区的分区方式被称作均分。默认情况下,当基本被分区的时候嵌套表会自动的被分区。然而你要注意的是,复合分区对于OCTs或者嵌套表是不支持的。

 

分区的好处

分区对于改善许多应用的性能、可管理性以及可用性提供了巨大的好处。分区技术对于包括查询或者维护操作在内的性能改善是极大的、非比寻常的。而且,分区技术还极大的简化了大多数常见的管理任务。

分区技术还能够使数据库设计者和管理者解决一些由前沿应用带来的棘手的问题。分区技术是建设TB级系统或者需要有极高可用要求的系统的关键工具。

下面我们从分区的性能、分区的可管理性和分区的可用性来了解一下分区技术的优点。

 

分区的性能

通过限制需要被检查的或者需要被操作的数据量,并且对于并行执行提供数据分布,分区技术提供了多种性能优势。分区技术包括以下两个功能:

Partition Pruning

分区裁剪是使用分区技术提高性能最简单也是最实质性的手段。分区裁剪常常能够通过几个数量级来提高查询性能。例如,假设有一个应用包含了一张Orders表,这张表包含了一些订单的历史记录,并且这张表是按照week来分区的。对于一个单周的查询订单的请求将只会访问这张Orders表的单个分区。如果这个Orders表有两年的历史数据,那么这个查询将会访问一个分区而不是104个分区。由于分区裁剪技术,这个查询比不分区要快了100倍左右。

分区裁剪技术可以与其他所有的Oracle性能特性一起工作,分区裁剪技术可以与任何索引技术、连接技术或者并行方法一起使用。

Partition-Wise Joins

分区技术通过使用一个名叫智能分区连接的技术也能够改善多表连接的性能。智能分区连接能够在两张分区表都使用连接key作为分区键做连接时被应用,或者当一个引用分区表与它的父表做连接时被使用。智能分区连接打破了大型的连接让更小的连接在每个分区之间发生,在更短的时间内完成整体连接。这个对于串行和并行都提供了显著的性能优势。

 

分区的可管理性

分区技术使你能够将表和索引分到更小的、更可管理的单元中,它提供了数据库管理员对数据管理分而治之的能力。使用分区技术,维护操作能够更专注于表中特定的部分。例如,你可以备份表的一个分区,而不是备份整个表。对于要涉及一整个数据库对象的维护操作,它能够基于每分区的基础上执行这些操作,因此它会分割维护进程到更多的可管理块中。

对于分区技术的可管理性的一个典型的用途就是支持一个滚动窗口将数据处理加载到一个数据仓库中。假设你要基于周来加载新的数据到一张表中,这个婊能够被分区以至于每个分区包含一周的数据。那么这个加载处理只要简单的使用分区交换加载技术添加一个新的分区就可以了。添加一个分区要比修改整张表来的高效的多,因为你不必去修改任何其他分区。

 

分区的可用性

分了区的数据库对象提供分区的独立性。这个分区独立的特点是高可用策略的一个重要组成部分。例如,如果一张分区表的一个分区不可用,那么这张表的所有其他的分区依然是保持在线和可用的。应用程序能够针对这张表可用的分区继续执行查询和事物,并且这些数据库操作能够被执行成功,他们不需要访问不可用的分区。

数据库管理员能够指定每个分区存储在一个分离的表空间中,最常见的场景就是让这些表空间存储在分离的存储件中。存储不同的分区在不同的表空间中能够使你对每一个独立的分区做备份和恢复操作,这些操作独立于这张表的其他分区。因此当不活动的数据仍然在被恢复的时候,数据库活动的部分能够被允许使其马上可用以用来能够连续的访问系统。而且,分区技术能够减少计划性的宕机时间。由分区技术提供的性能收益也许能够使你在相对小的批处理窗口中完成对于大数据库对象的维护操作。

 

分区策略

Oracle分区技术提供了三种基础的数据分布方法作为基本的分区策略来控制数据怎样放置到独立的分区中:

  • Range
  • Hash
  • List

使用这些数据分布方法,一张表能够使用一种单一的方法进行分区,或者被作为一个复合分区表进行分区。

每一种分区策略拥有不同的好处和设计注意事项。因此,每个策略都是更适合一种特定的场景。

 

Single-Level Partitioning

一张表指定了以下数据分布方法中的一种而被定义,它使用一个或多个字段作为分区键:

  • Range Partitioning
  • Hash Partitioning
  • List Partitioning

例如,考虑以下一张表有一个NUMBER类型的字段作为分区键,并且有两个分区less_than_five_hundredless_than_one_thousand。这个less_than_one_thousand分区所包含的行应该为以下内容:

下图提供了对于一个Single-Level 分区表的基本分区策略的图形化视图:

QQ图片20140328141849

 

Range Partitioning

Range分区基于你为每个分区建立的分区键的值的范围将数据映射到分区中。这个是最常用的分区类型并且通常与时间一起使用。对于一个用时间字段作为分区键的表,January-2010分区将会包含分区键的值在01-Jan-201031-Jan-2010的数据。

每个分区都有一个 VALUES LESS THAN子句,它指定了一个分区的非包容性上限。任何等于或高于分区键字面的值将会被添加到下一个更高的分区中。所有的分区,除了第一个分区,它们都有一个隐式的下限值,这个值由上一个分区的 VALUES LESS THAN子句指定。

MAXVALUE能够定义最高的分区。MAXVALUE代表了一个虚拟的无限值,这个值的排列要高于任何其他可能的分区键的值,包括NULL。

 

Hash Partitioning

Hash分区是基于一种Hash算法,Oracle将它应用在你指定的分区键上,让后将数据映射到分区中。这种hash算法将数据均匀分布在每个分区中,使分区拥有大致一样的大小。

Hash分区是将数据均匀分布在各设备的理想方式。Hash分区也是一个用来替代Range分区容易使用的方法,尤其是当这些被分区的数据不是历史数据,或者没有明显的分区键。

 

List Partitioning

List分区通过为一个分区键指定一个离散值的列表来对每个分区进行描述来控制数据怎样映射到分区中。列表分区的优点在于你能够使用一个很自然的途径去分组和组织没有规则和没有关系的数据集。对于一个有region地区字段作为分区键的表,East Sales Region分区可能会包含值为New YorkVirginiaFlorida的数据。

DEFAULT分区能够使你避免为一个list分区表指定所有可能的值,当有不匹配任何其他分区的数据出现时不会产生错误。

 

Composite Partitioning

复合分区是一个基础数据分布方法的组合。一张表被一种数据分布方法分区,并且每个分区再使用第二种数据分布方法细分到子分区中。一个给定分区的所有的子分区代表着一个数据的逻辑子集。

复合分区支持历史操作,比如添加一个新的range分区,但是通过子分区也提供了更高度的潜在的分区裁剪和细粒度的数据放置。

下图提供了一个range-hash和range-list复合分区作为示例的图形化视图:

QQ图片20140328150443

 

下面我们来了解以下分区类型:

  • Composite Range-Range Partitioning
  • Composite Range-Hash Partitioning
  • Composite Range-List Partitioning
  • Composite List-Range Partitioning
  • Composite List-Hash Partitioning
  • Composite List-List Partitioning

Composite Range-Range Partitioning

 

Range-Range复合分区能够使你沿两个维度进行逻辑范围分区。例如,通过order_date分区然后通过shipping_date进行范围子分区。

 

Composite Range-Hash Partitioning

Range-Hash复合分区将数据使用范围分区,然后将每个子分区使用Hash方式分区。Range-Hash复合分区提供改善了的range分区的可管理性和hash分区的数据放置、条带化和并行的优点。

 

Composite Range-List Partitioning

Range-List复合分区将数据通过range分区的方式分区,然后每个分区使用list的方式进行子分区。这种分区方式提供了range分区的可管理性和对于子分区使用列表分区的明确控制。

 

Composite List-Range Partitioning

List-Range复合分区能够对一个给定的list分区策略再进行逻辑范围子分区。例如,通过country_id进行list分区,使用order_date进行range子分区。

 

Composite List-Hash Partitioning

List-Hash复合分区能够对一个list分区对象进行hash子分区,例如,为了启用智能分区连接。

 

Composite List-List Partitioning

List-List复合分区能够使你从两个维度上进行逻辑列表分区,例如,使用country_id进行list分区,然后使用sales_channel进行list子分区。

 

分区扩展

对于基础分区策略的扩展,Oracle数据库提供了以下类型的分区扩展:

  • Manageability Extensions--管理性扩展
  • Partitioning Key Extensions--分区键扩展

Manageability Extensions--管理性扩展

以下扩展显著加强了分区表的可管理性:

  • Interval Partitioning
  • Partition Advisor

Interval Partitioning

Interval Partitioning是range分区的一个扩展,它实现了数据库在一个指定的间隔上自动创建分区,当插入表的数据超过了所有已经存在的范围分区。你必须至少指定一个范围分区。这个范围分区的键值决定着范围分区的上限值,这个也叫做转换点,并且这个数据库使用这个值为数据创建的间隔分区是要超越这个转换点的。每一个间隔分区的下限是前一个范围或间隔分区的非包容上限。

例如,如果你按月创建了一个间隔分区表,并且你设置转换点在January 1, 2007,那么对于January 2007间隔的下限就是January 1, 2007。July 2007间隔的下限就是July 1, 2007,无论June 2007这个分区是否被创建。

当使用间隔分区的时候考虑以下限制:

  • 你只能指定一个分区键字段,并且它必须是NUMBER类型或者是DATE类型。
  • 间隔分区不支持索引组织表
  • 你不能在一个间隔分区表上创建一个domain index。

你可以创建single-level间隔分区表,也可以创建以下的复合分区表:

  • Interval-range
  • Interval-hash
  • Interval-list

Partition Advisor

Partition Advisor是SQL Access Advisor的一部分。Partition Advisor能够为一个表提供一个分区策略,它是基于一个被提供的SQL语句的工作量,这个SQL语句可以由SQL Cache、一个SQL Tuning集或者用户自定的工作量提供。

 

Partitioning Key Extensions--分区键扩展

以下的扩展扩展了定义分区键的灵活性:

  • Reference Partitioning
  • Virtual Column-Based Partitioning

Reference Partitioning

Reference Partitioning能够使通过引用约束与另一张表产生关系的两张表进行分区。分区键通过一个已经存在了的父-子关系被处理,通过被启用了的和活动的主键和外键约束被强化。

这个扩展的好处是使具有父子关系的表能够通过从父表继承的分区键被逻辑的等分而不需要复制键的字段。这个逻辑倚赖也能够自动的级联分区维护操作,因此使应用开发更容易出现更少的错误。

一个引用分区的例子就是Orders表和LineItems表由一个引用约束orderid_refconstraint互相产生关系。也就是LineItems.order_id引用了Orders.order_id。这个Orders表在order_date上做了范围分区。在orderid_refconstraint上的引用分区引导LineItems去创建以下分区表,这个分区表在Orders表上被等分,如下图:

在进行引用分区之前

QQ图片20140328160644

使用了引用分区

QQ图片20140328160727

 

注意:所有的基础分区策略对引用分区都是可用的,但是对于间隔分区不支持。

 

Virtual Column-Based Partitioning

在之前的数据库版本中,表只能使用在表中物理存在的字段作为分区键进行分区。虚拟字段将这个限制移除了,并且使分区键可以被定义为一个表达式,这个表达式可以使用这个表中一个或多个已经存在的字段。这个表达式只作为元数据被存储。

Oracle分区已经被强化能够使一个分区策略被定义在一个虚拟字段上。例如,一个10位的account ID能够包含account的分支信息作为三个前导数字。对于基于虚拟字段分区的延伸,一个ACCOUNTS表包含一个ACCOUNT_ID字段,这个能够使用一个虚拟字段ACCOUNT_BRANCH被扩展。ACCOUNT_BRANCH是从ACCOUNT_ID字段的前三个数字导出的,而ACCOUNT_BRANCH能够成为这张表的分区键。

 

Partitioning Indexes

就像分区表一样,索引分区改善了可管理性、可用性、性能和可扩展性。它们能够被独立的分区(global indexes)或者自动的被连接到一张的的分区方法(local indexes)。通常来说OLTP应用你应该使用global indexes,数据仓库或者决策支持系统(DSS)应该使用local indexes。此外,只要有可能,就试着去使用local indexes,因为它们更容易管理。

下面我们来了解一下以下内容:

  • 决定要使用的分区索引的类型
  • 本地分区索引
  • 全局分区索引
  • 全局非分区索引
  • 在分区表上创建索引的一些其他信息
  • 复合分区上的分区索引

决定要使用的分区索引的类型

当你要决定使用哪种类型的分区索引时,你应该按照以下顺序遵循这个规则来考虑:

1. 如果表的分区字段是索引键的子集,那么使用本地索引。如果是这种情况,那么到此你就结束了。如果不是这种情况,请继续看指引2。

2. 如果是唯一索引并且不包含分区键的字段,那么使用全局索引。如果是这种情况,那么你就到此结束,否则请继续往下看指引3。

3. 如果你的优先级是可管理性,那么使用本地索引。如果是这种情况,那么你可以结束了,否则继续看指引4。

4. 如果应用是一个OLTP类型的用户需要快速的响应时间,那么使用全局索引。如果应用是一个DSS类型的并且用户更关注的是吞吐量,那么使用本地索引。

 

本地分区索引

本地分区索引比其他类型的分区索引更容易管理。它们也提供更好的可用性,通常使用在DSS环境中。这个原因是为了均摊:一个本地索引的每个分区都准确的与表的一个分区相关联。这个功能能够使Oracle自动保持索引分区与表分区的同步,并且使每个表-索引对独立。任何使一个分区的数据无效或不可能只会影响一个单分区。

本地分区索引支持更多的可用当表上有分区或子分区维护操作时。有一种名叫本地非前缀索引的索引对于历史数据库是非常有用的。在这种类型的索引中,分区不是在索引字段的左前缀上。

你不能明确的添加一个分区到一个本地索引。而是,只有当你在相关表上添加了一个分区的时候新分区才会被添加到本地索引。同样的,你不能明确的从一个本地索引上铲除一个分区。而是,只有当你铲除了相关的表的分区的时候本地索引分区才会被删除。

一个本地索引可以是唯一的。然而,为了让一个本地索引是唯一的,表的分区键必须是索引键字段的一部分。

下图提供了一个本地分区索引的图形化视图:

QQ图片20140328171414

 

全局分区索引

Oracle提供了全局范围分区索引和全局hash分区索引,下面我们来了解一下以下内容:

  • 全局范围分区索引
  • 全局Hash分区索引
  • 全局分区索引的维护

 

全局范围分区索引

全局范围分区索引是灵活的,它在分区的度和分区键上是独立于表分区的方法的。

全局索引的最高分区必须有一个分区边界,所有的这些值是MAXVALUE。这个确保了表中的所有的数据能够在索引中被对应。全局前缀索引可以是唯一的也可以为非唯一。

你不能给一个全局索引添加一个分区,因为最高的分区总是有一个MAXVALUE的分区边界。去添加一个新的最高分区,需要使用ALTER INDEX SPLIT PARTITION语句。如果一个全局索引分区是空的,你可以使用ALTER INDEX DROP PARTITION语句明确的将它删掉。如果一个全局索引包含数据,删除分区子句会导致下一个最高分区被标记为不可用。你不能删除一个全局索引的最高分区。

 

全局Hash分区索引

当一个索引单调增长的时候全局HASH分区索引通过分离处争用来改善性能。换而言之,大多数的索引插入只发生在一个索引的右边界。

 

全局分区索引的维护

默认情况下,以下在heap-organized表上的分区操作会标记所有的全局索引unusable:

这些索引能够通过添加UPDATE INDEXES子句到SQL语句中被维护。对于这样维护全局索引有以下两个好处:

  • 这个索引在这个操作过程中始终保持可用和在线,所以没有其他应用因为这个操作受影响。
  • 在这个操作之后索引不需要被重建。

下图提供了一张全局分区索引的图形化视图:

QQ图片20140328175228

 

 

全局非分区索引

全局非分区索引就像一个非分区索引一样,下图提供了一个全局非分区索引的图形化视图:

QQ图片20140328175533

 

在分区表上创建索引的一些其他信息

你可以创建bitmap索引在分区表上,但是bitmap索引必须是本地分区索引,它不能是全局索引。

全局索引可以是唯一的。本地索引只有在分区键是索引键一部分的情况下才能是唯一的。

 

复合分区上的分区索引

当在复合分区上使用分区索引时以下几点是需要牢记的:

  • 子分区索引总是本地的并且默认情况下与表的子分区存放在一起。
  • 表空间能够要么被指定在索引级别要么被指定在索引子分区子别。
请尊重我们的辛苦付出,未经允许,请不要转载 Ask600 的文章!