技术开发 频道

DB2 V9.7分区索引新特性

    创建分区索引

    在 DB2 V9.7 中,创建索引的语法增加了两个保留字 PARTITIONED 和 NOT PARTITIONED,分别用来创建分区索引和非分区索引。如果在创建索引时没有指定这两个保留字中任何一个,默认将建立分区索引。这就意味着,当用户在 DB2 V9.7 上使用于之前相同的语句创建索引时,事实上 DB2 数据库管理系统自动的为用户应用了分区索引这一新特性。

    我们已经知道,在 DB2 V9.7 之前,在分区表上创建索引(非分区索引)时可以使用“ CREATE INDEX … ON … IN <tablespace> ”语法将索引放到不同的表空间中,如图 1 所示。在 DB2 V9.7 中,我们仍然可以使用类似语句将非分区索引放到不同的表空间中,而对于分区索引,不允许在创建索引时指定“ IN <tablespace> ”子句,这是因为分区索引的特性,每个索引分区的存放位置取决于创建分区表时分区级“ INDEX IN <tablespace> ”子句,如果某个数据分区没有指定该字句,则相应的索引分区将存放在与数据分区相同的表空间中。

    创建索引的语句如清单 4 所示,这里创建了两个分区索引 purpleidx 和 greenidx,以及一个非分区的索引 blueidx 。

    清单 4. 创建分区索引以及非分区索引

    CREATE INDEX purpleidx on datapartT(a,b) PARTITIONED;

    CREATE INDEX greenidx on datapartT(b) PARTITIONED;

    CREATE INDEX blueidx on datapartT(a) NOT PARTITIONED;

    此时分区表 datapartT 中各个数据分区和索引的存放如图 3 所示。

图 3. 分区表上分区索引和非分区索引的存放
 

      在图 3 中,  分区 Part0,在创建表时指定了“ IN TbspD ”,没有分区级的 INDEX IN 子句,于是 Part0 的数据分区放在表空间 TbspD 中,相应的索引分区存放在相同的表空间 TbspD 中。

    分区 Part1,在创建表时没有指定分区级的 IN 子句,但是由于存在表级的“ IN TbspT ”,于是 Part1 的数据分区放在 TbspT,同时对于 Part1 指定了分区级的“ INDEX IN TbspY ”,于是 Part1 相应的索引分区放在表空间 TbspY 上。

    分区 Part2 和 Part3,都没有指定分区级 IN 字句,都有分区级的“ INDEX IN TbspW ”,于是这两个数据分区放在表空间 TbspT,相应的索引分区放在表空间 TbspW 中。

    分区 Part4,即没有指定分区级的 IN 子句,也没有指定分区级的 INDEX IN 子句,于是这个数据分区放在表级“ IN TbspT ”所指定的表空间 TbspT 中,索引分区放在与数据分区相同的表空间 TbspT 中。

    对于非分区索引 blueidx,在创建索引没有指定 IN 子句,根据规则这个索引将存放在创建表时的表级 INDEX IN 子句所指定的表空间中,即 TbspX 。

    分区索引管理

    在这里我们来介绍如何维护分区索引,包括

    如何判断分区索引

    如何取得分区索引的信息

    如何把非分区索引移植为分区索引。

    如何判断分区索引

    对于已经存在的数据库中的索引,我们如何判断是分区索引或非分区索引,可以通过 DB2 提供的命令 DESCRIBE INDEXES 来判断,使用的命令和结果如清单 5 所示。

    清单 5. 用 DESCRIBE 命令查看是否为分区索引

    db2 describe indexes for table datapartt

    Index Index Unique Number of Index Index

    schema name rule columns type partitioning

    ------ ------ ------ ------- --------- --------

    TESTUSERS PURPLEIDX D 2 RELATIONAL DATA P

    TESTUSERS GREENIDX D 1 RELATIONAL DATA P

    TESTUSERS BLUEIDX D 1 RELATIONAL DATA N 3 record(s) selected.

    在 DESCRIBE INDEXES 的输出中有一列“ Index partitioning ”,“ P ”表示该索引为分区表上的分区索引,“ N ”表示该索引为分区表上的非分区索引。如果所指定的不是分区表,对于表上的索引 DESCRIBE 将输出“ _ ”。

    如何取得分区索引的信息

    在故障诊断和数据恢复时,我们需要获得表和索引的一些基本信息,除了表名、索引名之外我们经常需要获得表和索引的对象 ID(object ID),表空间 ID 以及其他的信息,其中对象 ID 和表空间 ID 是两个最重要的信息,可以用来唯一标识数据库中的一个对象。

    我们可以通过熟知的 CATALOG 表中获取相应信息,我们已经知道,对于表和索引的基本信息,可以分别查询 SYSCAT.TABLES 和 SYSCAT.INDEXES 。查询语句和输出结果如清单 6 所示。

    清单 6. 查询 CATALOG 表获取表和索引信息

    select substr(tabname, 1,10) tabname, TABLEID ,TBSPACEID

    from syscat.tables where tabname='DATAPARTT'

    TABNAME TABLEID TBSPACEID

    ---------- ------- ---------

    DATAPARTT -32768

    -6 1 record(s) selected.

    select substr(TABNAME, 1,10)TABNAME,SUBSTR(INDNAME, 1, 10)

    INDNAME, INDEXTYPE, TBSPACEID, INDEX_OBJECTID

    from syscat.indexes where tabname='DATAPARTT'

    TABNAME INDNAME INDEXTYPE TBSPACEID INDEX_OBJECTID

    ---------- ---------- --------- ----------- --------------

    DATAPARTT PURPLEIDX REG 65530

    32768

    DATAPARTT GREENIDX REG 65530

    32768

    DATAPARTT BLUEIDX REG 10

    4 3 record(s) selected.

    对于分区表,从 SYSCAT.TABLES 中获取到的对象 ID 和表空间 ID 是逻辑 ID(-32768, -6),并不是表空间存储中真正的 ID,也并不存在这样一个物理的对象,这是因为分区表是由若干个数据分区组成的,每一个分区分别对应一个表空间中的数据对象。

    类似的,对于分区索引从 SYSCAT.INDEXES 中获取到的对象 ID 和表空间 ID 也是逻辑 ID(65530, 32768),同样原因是因为分区索引是由若干个索引分区组成,每个索引分区分别对应着一个表空间的索引对象。

    我们可以通过查询 SYSCAT.DATAPARTITIONS 来获取每一个数据分区的信息,使用的查询语句和输出的结果如清单 7 所示。

    清单 7. 查询 CATALOG 表获取每个数据分区信息

    select substr(DATAPARTITIONNAME, 1,10) DATAPARTITIONNAME, PARTITIONOBJECTID,

    tbspaceid ,substr(tabname,1,10) tabname

    from syscat.datapartitions where tabname='DATAPARTT'

    DATAPARTITIONNAME PARTITIONOBJECTID TBSPACEID TABNAME

    ----------------- ----------------- ----------- ----------

    PART0 4 11 DATAPARTT

    PART1 4 9 DATAPARTT

    PART2 5 9 DATAPARTT

    PART3 6 9 DATAPARTT

    PART4 7 9 DATAPARTT 5 record(s) selected.

    在结果中我们可以看到每一个数据分区都有各自的对象 ID 和表空间 ID,这里的 ID 都是物理 ID,对应一个数据库对象。

    对于分区索引的每一个索引分区,在 DB2 V9.7 中有一个新的 CATALOG 表 SYSCAT.INDEXPARTITIONS 来记录其信息,从这个表中我们也可以获取每一个索引分区唯一的对象 ID 和表空间 ID 。使用的查询语句和输出结果如清单 8 所示。

    清单 8. 查询 CATALOG 表获取每个索引分区的信息

    select substr(TABNAME, 1,10)TABNAME,SUBSTR(INDNAME, 1, 10) INDNAME,

    INDPARTITIONTBSPACEID, INDPARTITIONOBJECTID, DATAPARTITIONID

    from SYSCAT.INDEXPARTITIONS where tabname='DATAPARTT'

    TABNAME INDNAME INDPARTITIONTBSPACEID INDPARTITIONOBJECTID DATAPARTITIONID

    ------ ----- ------------ ------------ ----------

    DATAPARTT PURPLEIDX 11 4 0

    DATAPARTT PURPLEIDX 12 4 1

    DATAPARTT PURPLEIDX 13 4 2

    DATAPARTT PURPLEIDX 13 5 3

    DATAPARTT PURPLEIDX 9 7 4

    DATAPARTT GREENIDX 11 4 0

    DATAPARTT GREENIDX 12 4 1

    DATAPARTT GREENIDX 13 4 2

    DATAPARTT GREENIDX 13 5 3

    DATAPARTT GREENIDX 9 7 4 10 record(s) selected.

    在结果中我们发现一个现象,索引 purpleidx 的索引分区 0 对应的对象 ID 和表空间 ID 为(4,11),而索引 greeninx 的索引分区 0 对应的对象 ID 和表空间 ID 也是(4,11),其他的分区也有相同的重复问题,我们在上文也指出每一个对象有唯一的对象 ID 和表空间 ID,这是否矛盾呢?其实,对于每一个数据分区的所有索引分区,都是存放在同一个索引对象中,例如,对于数据分区 Part0,它对应两个索引分区分别是 purpleidx 的分区 0 和 greenidx 的分区 0,这两个索引分区都存放在对象 ID 和表空间 ID 为(4,11)的索引对象里。假如我们继续在这个 datapartT 表上创建更多的分区索引,那数据分区 Part0 相应的所有索引分区都将共享这一个索引对象(4,11)。

   

0
相关文章