分区表的索引行为

分区表的索引的工作方式与非分区表的索引类似。 但是,分区表的索引是使用不同存储模型存储的(根据索引是分区索引还是非分区索引)。

尽管常规非分区表的索引全都驻留在共享的索引对象中,但分区表的非分区索引将在单一表空间中它自己的索引对象中创建,即使数据分区跨多个表空间也是如此。 数据库管理的空间 (DMS) 和系统管理的空间 (SMS) 表空间都支持使用不同于表数据所在位置的位置中的索引。 可以将每个非分区索引放入它自己的表空间,其中包括大型表空间。 每个索引表空间都必须使用与数据分区相同的存储机制,即 DMS 或 SMS。 大型表空间中的索引可以包含多达 229 页。 所有表空间都必须在同一个数据库分区组中。

分区索引使用了索引组织方案,即,索引数据根据表的分区方案划分到多个索引分区中。 每个索引分区都只引用相应数据分区中的表行。 特定数据分区的所有索引分区都驻留在同一个索引对象中。

Db2® 版本 9.7 修订包 1 开始,用户创建的针对分区表中 XML 列的 XML 数据的索引可以是分区索引,也可以是非分区索引。 缺省情况下为分区索引。 系统生成的 XML 区域索引始终为分区索引,而系统生成的列路径索引始终为非分区索引。 在 Db2 9.7中,基于 XML 数据的索引是非分区索引。

非分区索引的优势包括:
  • 可以相互独立地对各个索引进行重组
  • 能够提高删除索引操作的性能
  • 删除各个索引时,空间将立即可供系统使用,而无需进行索引重组
分区索引的优势包括:
  • 能够提高数据滚入和滚出性能
  • 由于索引进行分区,因此能够减少对索引页的争用
  • 每个索引分区均采用索引 B 树结构,这有如下优点:
    • 提高插入、更新、删除和扫描性能,这是因为,索引分区的 B 树所包含的层数通常少于引用表中所有数据的索引
    • 改进分区消除生效时的扫描性能和并行性。 尽管分区消除功能既可用于分区索引扫描也可用于非分区索引扫描,但用于分区索引扫描却更为有效,这是因为,每个索引分区都只包含相应数据分区的键。 此配置可导致必须扫描的键数和索引页数少于对非分区索引执行的类似查询。

虽然非分区索引始终保留索引列的顺序,但分区索引在某些情况下可能会在各分区之间丢失一些顺序;例如,如果分区列与索引列不匹配,并且将访问多个分区。

在联机索引创建期间,允许对表进行并行读写访问。 构建联机索引后,在创建索引期间对表进行的更改将应用于新索引。 对该表所作的写访问将被阻塞,直到索引创建完成并且事务落实为止。 对于分区索引而言,仅当应用创建索引分区期间对数据分区所作的更改时,才会停顿每个数据分区以便进行只读访问。

当您使用 ALTER TABLE 来滚动数据时,分区索引支持变得特别有用 ...ATTACH PARTITION 语句。 如果存在非分区索引(不包括 XML 列路径索引,如果表包含 XML 数据的话),请在连接分区之后发出 SET INTEGRITY 语句。 非分区索引维护、范围验证、约束检查和具体化查询表 (MQT) 维护需要此语句。 非分区索引的维护工作可能相当耗时并需要大量日志空间。 请使用分区索引来避免此维护成本。

如果在连接操作后表上存在要维护的非分区索引 (XML 列路径索引除外) ,那么 SET INTEGRITY ...ALL IMMEDIATE UNCHECKED 语句的行为就好像它是 SET INTEGRITY ...IMMEDIATE CHECKED 语句。 执行所有完整性处理,非分区索引维护和表状态转换,就像执行 SET INTEGRITY ...已发出 IMMEDIATE CHECKED 语句。

图 1 图显示分区表上的两个非分区索引,每个索引位于单独的表空间中。
图 1。 分区表的非分区索引
独立表空间中分区表的非分区索引的插图。
图 2 图显示了分区表上的分区索引,该分区表跨越两个数据库分区并驻留在单个表空间中。
图 2。 分布式分区表的非分区索引
分区表上跨两个数据库分区且驻留在单个表空间中的非分区索引的插图。
图 3 图显示了分区表上的分区索引和非分区索引的混合。
图 3。 分区表的分区索引和非分区索引
分区表的分区索引和非分区索引的插图。

非分区索引 X1 引用所有数据分区中的行。 相反,分区索引 X2 和 X3 只引用与其相关联的数据分区中的行。 表空间 TS3 还显示了一些索引分区,这些索引分区共享与其相关联的数据分区的表空间。 对于分区索引而言,此配置是缺省情况。

您可以覆盖非分区索引和分区索引的缺省位置,尽管为这两种索引执行此操作的方法有所不同。 对于非分区索引,可以在创建该索引时指定表空间;对于分区索引,您需要在创建该表时确定用于存储索引分区的表空间。
非分区索引

要覆盖非分区索引的索引位置,请使用 CREATE INDEX 语句的 IN 子句为索引指定另一个表空间位置。 根据需要,可以将不同的索引放入不同的表空间。 如果创建分区表时未指定它的非分区索引的放置位置,并且使用未指定表空间的 CREATE INDEX 语句来创建索引,那么将在已连接的第一个数据分区或可视数据分区的表空间中创建该索引。 按顺序对下面三种可能情况进行评估(从情况 1 开始),以确定创建索引的位置。 找到匹配的情况时,此项用于确定索引的表空间位置的评估即停止。

案例 1:
在 CREATE INDEX 中指定索引表空间时 ...在
tbspace 语句中,将指定的表空间用于此索引。

案例 2:
在 CREATE TABLE 中指定索引表空间时 ...
INDEX IN tbspace 语句,将指定的
表空间用于此索引。

案例 3:
如果未指定表空间,请选择第一个连接的数据分区或可视数据分区所使用的表空间

分区索引
缺省情况下,索引分区将被放入它们所引用的数据分区所在的表空间。 要覆盖这种缺省行为,必须对您使用 CREATE TABLE 语句定义的每个数据分区使用 INDEX IN 子句。 换而言之,如果您计划对分区表使用分区索引,那么必须在创建该表时预测索引分区的存储位置。 如果您尝试在创建分区索引时使用 INDEX IN 子句,那么将接收到错误消息。
示例 1:给定分区表 SALES (a int, b int, c int),创建唯一索引 A_IDX。
   create unique index a_idx on sales (a)

由于表 SALES 是分区表,因此索引 a_idx 也将被创建为分区索引。

示例 2:创建索引 B_IDX。
   create index b_idx on sales (b)
示例 3:覆盖分区索引中索引分区的缺省位置,对您创建分区表时定义的每个分区使用 INDEX IN 子句。 在以下示例中,将在表空间 TS3 中创建表 Z 的索引。
create table z (a int, b int) 
      partition by range (a) (starting from (1)
      ending at (100)  index in ts3)

   create index c_idx on z (a) partitioned