【DB2】DB2基础_表分区

开始之前

CREATE TABLE 语句的 PARTITION BY 子句指定了表数据的分区。该定义中使用的列被称为表分区键列。

关于该特性的详细说明可参见 “Table partitioning in DB2 9”(developerWorks,2006 年 5 月)。

表分区特性提供以下收益:

  • 表数据可轻易实现转入和转出
  • 对大型表的管理更加轻松
  • 灵活的索引放置
  • 更高的业务智能样式查询的性能

关于本教程

本教程中的练习将引领您使用表分区特性,并演示了表数据的转入转出、更轻松的大型表管理、灵活的索引放置和对业务智能样式查询的性能改善。

这些练习旨在演示上述各领域内的一个或多个任务。

目标

本教程的目标是在以下方面探究 DB2 9 范围分区的特性和优点:

  • 创建范围分区表
  • 分区的转入和转出
  • 分区表的管理
  • 索引管理和放置

先决条件

本教程的目标读者是那些技能和经验刚刚迈入中级水平的 DB2 专业人员。要学习本教程,您应该熟悉 DB2 命令行、DB2 管理工具的使用,还应具备 SQL 实践经验。

系统需求

要运行本教程的示例,需要具备以下条件:

  • DB2 9 Data Server
  • Microsoft® Windows® 2000 或更高版本,以及一个具有管理员权限的帐户,或具有根访问权限的 Linux®(验证版)。
  • 确保系统中的 Java Runtime Environment 是 1.4.2 或更高版本。
  • 参考 DB2 9 系统需求页面 确保您的硬件符合要求。

可通过上面的链接获取 DB2 9 Express C。关于安装 DB2 的步骤请参考 “DB2 XML 评估指南”(developerWorks,2006 年 6 月)。若未改动 DB2 的配置,安装后 DB2 将自动启动。

使用 partition.zip 文件提供的示例脚本和数据演示本教程的概念。将其内容解压缩到 scripts 子目录(C:\scripts 或 home/userid/scripts)。本教程中将该目录简称为 stmm_scripts。教程假设您使用的是 DB2 默认安装目录,并且所有的 DB2 练习都通过一个数据库管理员 ID 执行。

创建分区表

这个实验将探讨创建分区表、将数据载入分区表以及使用 describe 命令来说明表范围的方法:

  1. 您将登录并为所有的练习设置基本环境。
  2. 您将创建不同格式的分区表并加载数据。
  3. 您将使用 DB2 命令和 SQL 查看结果。
  4. 将对 DB2 9 表范围分区进行概述。

登录和基本指令

  1. 登录到您的机器,如图 1 所示,使用 db2inst1。

    图 1. 基本设置

    s5.jpg

  2. 打开终端窗口(Linux)或 DB2 命令窗口(windows)。

  3. 切换到 scripts 子目录。

    清单 1. 切换目录

    1
    2
    cd /scripts or 
    cd c:\scripts
  4. 使用db2start命令启动 DB2,并连接到 SAMPLE 数据库。

    清单 2. StartDB2

    1
    2
    db2start
    db2 connect to SAMPLE

创建基本分区表

这一节将介绍分区表的基本创建和加载。您将创建不同格式的表、验证创建结果、加载数据并对表进行查询。

  1. 使用如下的数据定义语言(DDL)创建具有四个范围的 LINEITEM 表:

    清单 3. 创建表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    CREATE TABLE LINEITEM 
    ( l_orderkey DECIMAL(10,0) NOT NULL,
    l_partkey INTEGER,
    l_suppkey INTEGER,
    l_linenumber INTEGER,
    l_quantity DECIMAL(12,2),
    l_extendedprice DECIMAL(12,2),
    l_discount DECIMAL(12,2),
    l_tax DECIMAL(12,2),
    l_returnflag CHAR(1),
    l_linestatus CHAR(1),
    l_shipdate DATE,
    l_commitdate DATE,
    l_receiptdate DATE,
    l_shipinstruct CHAR(25),
    l_shipmode CHAR(10),
    l_comment VARCHAR(44))
    PARTITION BY RANGE(l_shipdate)
    ( STARTING '1/1/1992' ENDING '30/06/1992',
    STARTING '1/7/1992' ENDING '31/12/1992',
    STARTING '1/1/1993' ENDING '30/6/1993',
    STARTING '1/7/1993' ENDING '31/12/1993')

    创建该表的 SQL 语句位于 EX1-6.sql 文件中,可使用如下命令运行该文件:

    清单 4. 运行 EX1-6

    1
    db2 –vtf EX1-6.sql
  2. 使用下面的命令说明为 LINEITEM 表创建的分区的范围:

    清单 5. 说明

    1
    db2 describe data partitions for table LINEITEM

    图 2. 说明为 LINEITEM 表创建的分区范围

    s6.jpg

    注意:创建了四个数据分区。其中的范围包括边界值。

  3. 将数据导入到 LINEITEM 表。该操作的导入命令位于 EX1-8.sql 文件中,可使用如下命令运行:

    清单 6. 带有拒绝的加载

    1
    db2 –vtf EX1-8.sql

    图 3. 将数据导入到 LINEITEM 表

    s7.jpg

    注意:导入时拒绝了 729 行数据,这是因为它们不具有位于当前 LINEITEM 表的数据分区定义范围内的 l_shipdate。

  4. 标量函数可用于显示行所属的数据分区号(datapartitionnum)。执行以下示例 SQL 查看标量函数的输出:

    清单 7. 查询 - 匹配日期的分区

    1
    2
    3
    db2 "select datapartitionnum(l_shipdate) as PartitionId, l_shipdate from lineitem 
    where l_shipdate between '01/06/1992' and '31/07/1992'
    order by l_shipdate"

    图 4. 标量函数的输出

    s8.jpg

    注意:标量函数(datapartitionnum)返回的值和describe 命令返回的是同一个 PartitionId。该语句的子句间使用的谓词范围超出了 PartitionId 0 和 PartitionId 1 的边界

具有全部范围的分区表

  1. 创建具有两个额外数据分区的新 LINEITEM 表,其中一个分区用来捕获低于当前范围的值,另一个分区用来捕获高于当前范围的值。首先使用下面的命令删除现有的 LINEITEM 分区表:

    清单 8. 删除表

    1
    db2 drop TABLE LINEITEM

    然后使用如下 DDL 创建 LINEITEM 表的新版本:

    清单 9. 创建表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    CREATE TABLE LINEITEM 
    ( l_orderkey DECIMAL(10,0) NOT NULL,
    l_partkey INTEGER,
    l_suppkey INTEGER,
    l_linenumber INTEGER,
    l_quantity DECIMAL(12,2),
    l_extendedprice DECIMAL(12,2),
    l_discount DECIMAL(12,2),
    l_tax DECIMAL(12,2),
    l_returnflag CHAR(1),
    l_linestatus CHAR(1),
    l_shipdate DATE,
    l_commitdate DATE,
    l_receiptdate DATE,
    l_shipinstruct CHAR(25),
    l_shipmode CHAR(10),
    l_comment VARCHAR(44))
    PARTITION BY RANGE(l_shipdate)
    ( STARTING MINVALUE,
    STARTING '1/1/1992' ENDING '30/06/1992',
    STARTING '1/7/1992' ENDING '31/12/1992',
    STARTING '1/1/1993' ENDING '30/6/1993',
    STARTING '1/7/1993' ENDING '31/12/1993',
    ENDING MAXVALUE)

    创建该表的 SQL 位于 EX1-10.sql 文件中,可使用下列命令运行:

    清单 10. 运行 EX1-10

    1
    db2 –vtf EX1-10.sql
  2. 使用下面的命令说明为 LINEITEM 表创建的分区范围。

    清单 11. 说明

    1
    db2 describe data partitions for table LINEITEM

    图 5. 说明为 LINEITEM 表创建的分区范围

    s10a.jpg

    注意:新的 MINVALUE 范围具有一个最高值,该值和下一个数据分区开始部分的值相等,但它并不包含该值。MAXVALUE 范围具有一个最低值,该值和前一个范围结束部分的值相等,但它不包含该值。这将创建一个无间隙的连续范围。

  3. 将数据导入到 LINEITEM 表中。该操作的导入命令位于 EX1-8.sql 文件中,可使用下面的命令运行该文件:

    清单 12. 全面加载

    1
    db2 –vtf EX1-8.sql

    图 6. 将数据导入到 LINEITEM 表中

    s10b.jpg

具有生成范围的分区表

  1. 创建一个新 LINEITEM 表,它具有从 1992 年 1 月 1 日到 1998 年 12 月 31 日按月划分的数据分区生成范围。同样,添加 minvalue 和 maxvalue 范围来存放具有超过此范围的 l_shipdate 的值的行。首先使用以下命令删除现有的 LINEITEM 分区表:

    清单 13. 删除表

    1
    db2 drop TABLE LINEITEM

    然后使用如下 DDL 创建 LINEITEM 表的新版本:

    清单 14. 创建表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    CREATE TABLE lineitem
    (l_orderkey DECIMAL(10,0) NOT NULL,
    l_cpartkey INTEGER,
    l_suppkey INTEGER,
    l_linenumber INTEGER,
    l_quantity DECIMAL(12,2),
    l_extendedprice DECIMAL(12,2),
    l_discount DECIMAL(12,2),
    l_tax DECIMAL(12,2),
    l_returnflag CHAR(1),
    l_linestatus CHAR(1),
    l_shipdate DATE,
    l_commitdate DATE,
    l_receiptdate DATE,
    l_shipinstruct CHAR(25),
    l_shipmode CHAR(10),
    l_comment VARCHAR(44))
    PARTITION BY RANGE(l_shipdate)
    (STARTING MINVALUE,
    STARTING '1/1/1992' ENDING '31/12/1998'
    EVERY 1 MONTH,
    ENDING MAXVALUE);

    创建该表的 SQL 位于 EX1-13.sql 文件中,可使用下面的命令运行该文件:

    清单 15. 运行 EX1-13

    1
    db2 –vtf EX1-13.sql
  2. 使用如下命令来说明为 LINEITEM 表创建的分区范围:

    清单 16. 说明

    1
    db2 describe data partitions for table LINEITEM

    图 7. 说明为 LINEITEM 表创建的分区范围

    s12a.jpg

    注意:创建了 86 个数据分区,但是没有包括这些范围的最高值,因为这些最高值将和之后的数据分区的最低值重叠。

  3. 将数据导入到 LINEITEM 表。此操作的导入命令位于 EX1-8.sql 文件中,可使用下面的命令运行该文件:

    清单 17. 加载并生成

    1
    db2 –vtf EX1-8.sql

    图 8. 将数据导入到 LINEITEM 表

    s12b.jpg

  4. 使用下面的 SQL 来验证 LINEITEM 表每一个数据分区的行数:

    清单 18. 查询数据

    1
    2
    3
    4
    db2 "select year(l_shipdate) as year, month(l_shipdate) as month, 
    count(*) as count from lineitem
    group by year(l_shipdate), month(l_shipdate)
    order by 1, 2"

    使用以下的 SQL 语句验证 LINEITEM 表的每一个数据分区的行数:

    清单 19. 查询数据脚本

    1
    db2 –vtf EX1-16.sql

    图 9. 检验行数

    s13.jpg

    注意:执行加载操作后,86 个范围中有 82 个范围包含一个或多个行。

放置分区表

该实验探讨放置分区表以及使用 describe 命令说明表内的范围和放置情况的方法:

  1. 您将为数据放置练习创建新的表空间。
  2. 你将创建不同格式的分区表。
  3. 您将使用 db2 命令和 SQL 查看结果。

基本环境设置

  1. 使用describe data partitions命令以及show detail方法来显示表空间的分区放置。

    清单 20. 创建表

    1
    db2 describe data partitions for table LINEITEM show detail

    图 10. 表空间的分区放置

    s14.jpg

    注意:TableSpID 列给出了包含分区的表空间的 ID 号。在本例中,TableSpID 是 ‘3’。

  2. 使用list tablespaces命令标识与 TableSpId 相关联的表空间。

    清单 21. 说明

    1
    db2 list tablespaces

    图 11. 标识表空间

    s15.jpg

    注意:相应值为 ‘2’ 的 TableSpID 是 USERSPACE1 或默认的表空间。

  3. 现在将创建五个表空间来说明不同的放置选项。使用如下命令:

    清单 22. 说明

    1
    2
    3
    4
    5
    db2 create tablespace dms_d1 managed by database using (file 'c:\ts1' 10000);
    db2 create tablespace dms_d2 managed by database using (file 'c:\ts2' 10000);
    db2 create tablespace dms_d3 managed by database using (file 'c:\ts3' 10000);
    db2 create tablespace dms_d4 managed by database using (file 'c:\ts4' 10000);
    db2 create tablespace dms_i1 managed by database using (file 'c:\ts5' 10000);

    创建该表空间的 SQL 位于 EX2-3.sql 文件中,可使用下面的命令运行该文件:

    清单 23. 查询数据脚本

    1
    db2 –vtf EX2-3.sql
  4. 创建一个新的 LINEITEM 表,具有位于 dms_d1 和 dms_d2 表空间的生成分区集。首先,使用如下命令删除现有的 LINEITEM 分区表:

    清单 24. 删除表

    1
    db2 drop TABLE LINEITEM

    然后,使用下面的 DDL 创建 LINEITEM 表的新版本:

    清单 25. 创建表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    CREATE TABLE LINEITEM
    (l_orderkey DECIMAL(10,0) NOT NULL,
    l_partkey INTEGER,
    l_suppkey INTEGER,
    l_linenumber INTEGER,
    l_quantity DECIMAL(12,2),
    l_extendedprice DECIMAL(12,2),
    l_discount DECIMAL(12,2),
    l_tax DECIMAL(12,2),
    l_returnflag CHAR(1),
    l_linestatus CHAR(1),
    l_shipdate DATE,
    l_commitdate DATE,
    l_receiptdate DATE,
    l_shipinstruct CHAR(25),
    l_shipmode CHAR(10),
    l_comment VARCHAR(44))
    IN DMS_D1, DMS_D2
    PARTITION BY RANGE(l_shipdate)
    (STARTING MINVALUE,
    STARTING '1/1/1992'
    ENDING '31/12/1998' EVERY 1 MONTH,
    ENDING MAXVALUE);

    创建该表的 SQL 位于 EX2-4.sql 文件中,可使用下面的命令运行该文件:

    清单 26. 运行 EX2-4

    1
    db2 –vtf EX2-4.sql
  5. 使用下面的命令说明为 LINEITEM 表创建的分区范围:

    清单 27. 说明

    1
    db2 describe data partitions for table LINEITEM show detail

    图 12. 说明为 LINEITEM 表创建的分区范围

    s17a.jpg

    图 13. 分区

    s17b.jpg

    注意:TableSpID 列给出了包含分区的表空间的 ID 号。在本例中,TableSpID 为 4(对应于 DMS_D1)或 5(对应于 DMS_D2)。本例中将生成的分区依次分配给指定的表空间。

分区的显式放置

  1. 创建一个具有四个数据分区的新 LINEITEM 表,每一个数据分区被显式地放在表空间中。首先使用如下命令删除现有的 LINEITEM 表:

    清单 28. 删除表

    1
    db2 drop TABLE LINEITEM

    然后使用下面的 DDL 创建 LINEITEM 表的新版本:

    清单 29. 创建表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    CREATE TABLE LINEITEM
    (l_orderkey DECIMAL(10,0) NOT NULL,
    l_partkey INTEGER,
    l_suppkey INTEGER,
    l_linenumber INTEGER,
    l_quantity DECIMAL(12,2),
    l_extendedprice DECIMAL(12,2),
    l_discount DECIMAL(12,2),
    l_tax DECIMAL(12,2),
    l_returnflag CHAR(1),
    l_linestatus CHAR(1),
    l_shipdate DATE,
    l_commitdate DATE,
    l_receiptdate DATE,
    l_shipinstruct CHAR(25),
    l_shipmode CHAR(10),
    l_comment VARCHAR(44))
    PARTITION BY RANGE(l_shipdate)
    ( STARTING MINVALUE IN DMS_D1,
    STARTING '1/1/1992' ENDING '31/12/1992' IN DMS_D2,
    STARTING '1/1/1993' ENDING '31/12/1993' IN DMS_D3,
    ENDING MAXVALUE IN DMS_D4 );

    创建表的 SQL 位于 EX2-6.sql 文件中,可使用下面的命令运行该文件:

    清单 30. 运行 EX2-6

    1
    db2 –vtf EX2-6.sql
  2. 使用下面的命令说明为 LINEITEM 表创建的分区范围:

    清单 31. 说明

    1
    db2 describe data partitions for table LINEITEM show detail

    图 14. 说明为 LINEITEM 表创建的分区范围

    s19.jpg

    注意:在本例中,每一个分区被放置在一个不同的 TableSpID 中,这个 TableSpID 和创建表的 DDL 中指定的表空间是相对应的。

  3. 创建一个具有四个数据分区的 LINEITEM 表,每一个数据分区被显式地放在表空间并且索引被放在表空间 DMS_I1 中。 在这一步中,将引入命名分区的概念,而不是使用默认的生成名称。 首先,使用下面的命令删除现有的 LINEITEM 分区表:

    清单 32. 删除表

    1
    db2 drop TABLE LINEITEM

    然后,使用以下的 DDL 创建 LINEITEM 表的新版本:

    清单 33. 创建表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    CREATE TABLE LINEITEM
    (l_orderkey DECIMAL(10,0) NOT NULL,
    l_partkey INTEGER,
    l_suppkey INTEGER,
    l_linenumber INTEGER,
    l_quantity DECIMAL(12,2),
    l_extendedprice DECIMAL(12,2),
    l_discount DECIMAL(12,2),
    l_tax DECIMAL(12,2),
    l_returnflag CHAR(1),
    l_linestatus CHAR(1),
    l_shipdate DATE,
    l_commitdate DATE,
    l_receiptdate DATE,
    l_shipinstruct CHAR(25),
    l_shipmode CHAR(10),
    l_comment VARCHAR(44))
    INDEX IN DMS_I1
    PARTITION BY RANGE(l_shipdate)
    ( PART JAN1992 STARTING '1/1/1992' ENDING '30/6/1992' IN DMS_D1,
    PART JULY1992 STARTING '1/7/1992' ENDING '31/12/1992' IN DMS_D2,
    PART JAN 1993 STARTING '1/1/1993' ENDING '30/6/1993' IN DMS_D3,
    PART JULY1993 STARTING '1/7/1993' ENDING '31/12/1993' IN DMS_D4);

    创建表的 SQL 位于 EX2-8.sql 文件中,可使用下面的命令运行该文件:

    清单 34. 运行 EX2-8

    1
    db2 –vtf EX2-8.sql
  4. 在 LINEITEM 表中创建一个索引,并将它放置在表空间 DMS_I1 中。使用如下 SQL:

    清单 35. 索引

    1
    db2 "create index I_LINEITEM on LINEITEM(L_SHIPDATE) in DMS_I1"
  5. 使用下面的 SQL 检验和该表相关联的索引的位置:

    清单 36. 说明

    1
    db2 "select tabname, index_tbspace from syscat.tables where tabname = 'LINEITEM'"

    图 15. 检验索引的位置

    s21.jpg

    注意:索引空间是 DMS_I1。如果没有为分区表指定表空间,那么默认情况下索引位于连接着的第一个表空间。 在 CREATE TABLE 中定义表空间是很好的实践。然而,无论您是否在创建表语句 ID 中指定索引表空间,这并不限制您将来放置索引的位置。您可以在 CREATE INDEX 语句本身显式地指定索引表空间。 同一分区表的不同索引可以放置在不同的表空间。

管理分区表

这个实验将查看如何管理和操作分区表:

  1. 您将添加和删除分区。
  2. 您将执行对分区的转入转出操作。
  3. 在执行查看操作时将使用 DB2 命令和 SQL。

使用现有的表添加一个新的分区

  1. 将数据导入 LINEITEM 表。创建表空间的 SQL 位于 EX3-1.sql 文件中,可使用下面的命令运行该文件:

    清单 37. 导入数据

    1
    db2 –vtf EX3-1.sql

    图 16. 将数据导入到 LINEITEM 表

    s22a.jpg

    注意:分区表中的记录数,以及将进行连接和分离的记录数对于说明数据库中的数据何时可用非常重要。

  2. 创建一个名为 NP_LINEITEM 的新表。脚本 EX3-2.sql 创建一个具有 87 行的新表 NP_LINEITEM:

    清单 38. 新分区

    1
    db2 –vtf EX3-2.sql

    图 17. 将数据导入到 NP_LINEITEM 表

    s22b.jpg

  3. 使用下面的命令说明为 LINEITEM 表创建的分区范围:

    清单 39. 说明

    1
    db2 describe data partitions for table LINEITEM show detail

    图 18. LINEITEM 表的分区

    s23a.jpg

    注意:LINEITEM 表目前包含 4 个数据分区。

  4. 使用Alter语句将一个新的分区连接(转入)到现有的 LINEITEM 表。

    清单 40. 新分区

    1
    2
    3
    ALTER TABLE LINEITEM ATTACH PARTITION JAN1994
    STARTING '1/1/1994' ENDING '30/6/1994'
    FROM NP_LINEITEM

    可以使用以下命令运行脚本 EX3-4:

    清单 41. 新分区

    1
    db2 –vtf EX3-4.sql

    图 19. 脚本 EX3-4

    s23b.jpg

    注意:LINEITEM 表被置于 SET INTEGRITY PENDING 状态。

  5. 连接后,使用describe data partitions命令来说明为 LINEITEM 表创建的分区范围:

    清单 42. 说明

    1
    db2 describe data partitions for table LINEITEM show detail

    图 20. LINEITEM 表的分区

    s24.jpg

    注意:新数据分区(JAN1994)PartitionId 4 现在连接到了 LINEITEM 表。然而连接的分区的 AccessMode 值为 ‘N’ 并且 Status 的值为 ‘A’。 AccessMode 可能的值有:

    • D = 没有数据移动
    • F = 完全访问
    • N = 不访问
    • R = 只读访问

    Status 可能的值有:

    • A = 数据分区是新连接的
    • D = 数据分区是分离的
    • I = 只有在执行异步索引清除时才对条目位于目录的分离的数据分区进行维护;当所有引用分离数据分区的索引记录删除后,将删除 STATUS 值为 ‘I’ 的行。
    • Empty string = 数据分区是可见的(普通状态)
  6. 运行两个select count语句来检查连接语句涉及的两个表中数据的可用性。

    清单 43. Count Lineitem

    1
    db2 "select count(*) from lineitem"

    图 21. select count 语句的结果

    s25a.jpg

    注意:LINEITEM 表最初的分区是可用的,但是 PartitionId 4 中的新数据仍不可见。

    清单 44. Count np-lineitem

    1
    db2 "select count(*) from np_lineitem"

    图 22. select count 语句的结果

    s25b.jpg

    注意:NP_LINEITEM 表现在是一个未定义的对象,在 LINEITEM 表内只能将其作为一个分区使用。

  7. 创建一个异常表并与 SET INTEGRITY 语句结合使用。执行该操作的 DDL 位于 EX3-7.sql 文件,可使用下面的命令运行该文件:

    清单 45. 异常表

    1
    db2 –vtf EX3-7.sql
  8. 对 LINEITEM 分区表运行set integrity语句 。

    清单 46. 设置完整性

    1
    2
    3
    4
    SET INTEGRITY FOR LINEITEM
    ALLOW WRITE ACCESS
    IMMEDIATE CHECKED
    FOR EXCEPTION IN LINEITEM USE LINEITEM_EX

    执行该操作的 SQL 位于 EX3-8.sql 文件中,可以使用下面的命令运行该文件:

    清单 47. 设置完整性

    1
    db2 –vtf EX3-8.sql

    图 23. EX3-8.sql 文件

    s26a.jpg

    注意:SET INTEGRITY对于检查新连接的数据是否在范围内是必需的,它还执行对索引和其他独立对象(例如物化查询表)所有必需的维护工作。只有得到SET INTEGRITY语句的允许,新的数据才能变为可见。然而,当运行SET INTEGRITY时,可以对 LINEITEM 表中的现有数据进行完全访问,包括读和写操作。 用户应该执行SET INTEGRITY事务从而能够使用整个表。当运行SET INTEGRITY时,不能够对表执行 DDL 或其他实用类型的操作。 在这个练习中,在 NP_LINEITEM 表中创建并被连接到 LINEITEM 表的所有的行,都在连接语句指定的范围内。如果这些行中存在超出此范围的行,则需要在SET INTEGRITY语句中创建一个异常表来防止语句发生错误。所以推荐您始终在SET INTEGRITY语句中包含一个异常表。如果没有提供异常表的话,SET INTEGRITY语句发现的错误将导致语句失败并且所有的工作都必须从头做起。如果使用大量数据时,这可能是一个长期操作。有一点值得注意,如果SET INTEGRITY操作失败,所有工作都需要重做,与之相比较,LOAD仅仅抛弃存在问题的行。

  9. 对 LINEITEM 表运行select count SQL 以检查连接的分区中数据的可用性:

    清单 48. Count Lineitem

    1
    db2 "select count(*) from lineitem"

    图 24. select count 语句的结果

    s26b.jpg

    注意:成功执行SET INTEGRITY操作后,LINEITEM 表应包含 PartitionId 4 的数据。

从分区表中分离一个分区

  1. 使用describe data partitions show detail命令来标识一个分区的 PartitionName,您将把这个分区从 LINEITEM 分区表中分离(转出)出来。

    清单 49. 说明表

    1
    db2 describe data partitions for table LINEITEM show detail

    图 25. LINEITEM 表的分区

    s27a.jpg

    注意:将分离最早的分区范围 PartitionId 0。该分区的 PartitionName 是 JAN1992。将在DETACH操作中使用它来标识被转出的分区。同样还需注意成功执行了SET INTEGRITY操作后,分区 JAN1994 的 AccessMode 的值为 ‘F’,Status 值为空。TableSpId、PartObjId 和 LongTblSpId 的结果可能和这里显示的不一样。

  2. 使用Alter语句将 JAN1992 从 LINEITEM 表中分离(转出)。

    清单 50. Alter 表

    1
    ALTER TABLE LINEITEM DETACH PARTITION JAN1992 INTO LINEITEM_JAN1992

    创建文件的 SQL 位于 EX3-11.sql 文件中,可使用下面的命令运行该文件:

    清单 51. Alter 表

    1
    db2 –vtf EX3-11.sql

    注意:将 JAN1992 成功分离后,将创建一个新的表 LINEITEM_JAN1992。在DETACH操作中没有涉及数据移动,并且位于相同表空间的新表的行为和它作为 LINEITEM 分区表的一部分时是一样的。此时不需要对 LINEITEM 表运行SET INTEGRITY语句,因为没有对 LINEITEM 表定义的 MQTs。 还有一点值得注意,如果从 Multi-Dimensional Clustering(MDC)分离一个分区从而创建了一个新表时,这个表也将是一个 MDC。这个规则同样适用于下面这个情况:从一个分布式表中分离分区从而在相同的分区组创建分布式表。执行DETACH操作后产生的表使用 MDC 索引定义而不是其他的索引。对于 MDC,在首次访问连接的表时将重新构建索引。在这种情况下,将自动对分离的分区进行索引清除操作。将从执行DETACH操作的用户 ID 继承索引的模式、权限和表空间。

  3. 运行两个select count语句检查DETACH语句涉及的两个表中的数据的可用性。

    清单 52. Count Lineitem_jan1992

    1
    db2 "select count(*) from lineitem_jan1992"

    图 26. select count 语句的结果

    s28a.jpg

    注意:创建的 LINEITEM_JAN1992 表包含 38 行,它被包含在 LINEITEM 分区表的 JAN1992 分区中。

    清单 53. Count lineitem

    1
    db2 "select count(*) from lineitem"

    图 27. select count 语句的结果

    s28b.jpg

    注意:此时 LINEITEM 表完全可用,并且不包括 PART0 中的数据。

  4. 当数据被移动到分区表中,或当希望将数据加载到或直接插入分区表中时,一个更合适的方法是向现有的分区表添加一个空的分区。使用下面的命令向现有的 LINEITEM 表添加一个空的分区:

    清单 54. 说明

    1
    2
    db2 "ALTER TABLE LINEITEM ADD PARTITION JULY1994 
    STARTING '1/7/1994' ENDING '31/12/1994'""

    图 28. 向现有的 LINEITEM 表添加一个空的分区

    s28c.jpg

  5. 使用describe data partitions show detail命令来检验 PartitionName 为 JULY1994 的分区是否被添加到 LINEITEM 中:

    清单 55. 说明

    1
    db2 describe data partitions for table LINEITEM show detail

    图 29. LINEITEM 表的分区

    s29.jpg

分区表的访问计划

本实验将研究如何在访问计划中描述分区表:

  1. 您将更新分区表中的统计信息。

  2. 您将使用 db2expln 命令并分析结果。

  3. 您将在执行查看的操作中使用 DB2 命令和 SQL 。

  4. 对 LINEITEM 表执行RUNSTATS操作:

    清单 56. Runstats

    1
    db2 runstats on table db2inst1.lineitem
  5. 说明以下 SQL 语句并检查说明输出:

    清单 57. 说明

    1
    db2 "select l_shipdate,sum(l_quantity) from LINEITEM group by l_shipdate"

    要进行说明的 SQL 位于 EX4-2.sql 文件,可以使用下面的命令运行该文件:

    清单 58. 说明输出

    1
    db2expln –d SAMPLE –t –f EX4-2.sql

    图 30. 说明输出

    s30.jpg

    注意:该 SQL 执行了 LINEITEM 表的索引扫描。说明输出中有一个关于表分区的要点需要注意,所访问的表是被分区的,并且在扫描过程中所有数据分区都将被访问。

  6. 说明下面的 SQL 语句并检查说明输出:

    清单 59. 说明

    1
    2
    3
    4
    db2 "select l_shipdate, l_partkey, l_returnflag
    from LINEITEM
    where l_shipdate between '01/01/1993' and '31/08/1993'
    and l_partkey = 49981"

    要进行说明的 SQL 语句位于 EX4-3.sql 文件中,可使用下面的命令运行该文件:

    清单 60. 说明输出

    1
    db2expln –d SAMPLE –t –f EX4-3.sql

    图 31. 说明输出

    s31.jpg

    注意:这个 SQL 语句执行了 LINEITEM 表的索引扫描。在本例中,可以看到优化器能够执行数据分区排除操作。在说明输出中要注意的是关于表分区,访问的表是被分区的,将执行分区排除功能以及删除活动数据分区的值。 在本例中,活动的数据分区为 1-2。这里引用的是 syscat.datapartitions 中的序列号(seqno)而不是describe data partitions命令中的 PartitionId。

  7. 使用下面的 SQL 确定在前面说明示例中活动的分区的名称:

    清单 61. 说明

    1
    2
    3
    db2 "select seqno,datapartitionname
    from syscat.datapartitions
    where tabname = ‘LINEITEM’ order by seqno"

    图 32. 分区名称

    s32.jpg

    注意:序列号 1 和 2 分别映射的是 JAN1993 和 JULY1993 分区名称。

结束语

本教程基于 IBM DB2 9 Data Partitioning 特性。您已在以下几个方面获得了第一手的经验:

  • 如何定义分区表
  • 如何将分区表放置在底层磁盘子系统
  • 如何维护分区表
  • 如何使用 DB2 Explain 说明分区表

范围分区将数据映射到基于关键值范围的分区,用户为每一个分区建立关键值范围。例如,企业通常希望以月份为单位,将销售数据划分到各月的分区中。与 MDC 功能集合使用时,范围分区将更加方便地定位数据,从而加快通过复杂查询检索信息的速度。

下载资源

本文转载自IBM官方网站,原文地址:https://www.ibm.com/developerworks/cn/education/data/dm0612read/dm0612read.html