技术开发 频道

新版性能大幅提升 IBM DB2 10.1首测

        【IT168 专稿】DB2是美国IBM公司开发的一套关系型数据库管理系统,它主要的执行环境为UNIX、Linux、z/OS,以及Windows服务器操作系统。版本包括Express、Express-C、Workgroup和Enterprise版本。注意:企业版也不包括数据仓库功能、该功能需要用到另一个产品InfoSphere Warehouse 。DB2的版本进化较慢,2006年发布DB2 9后,直到2011年才发布10 for z/OS和9.8 pureScale,目前最新的版本是db2 10.1 for LUW(Linux、UNIX以及Windows),本文就是基于这个版本展开评测的。

  测评的内容主要包括3方面,分别是数据库安装、数据库新功能以及性能提高,其中新功能着重测试数据压缩、ingest导入工具和兼容Oracle功能,性能仍然围绕tpc-h展开。

  一、数据库安装

  IBM公司在其DB2 10 技术资源中心提供了最新的db2 10.1版本的相关信息,这里也提供了评估版软件下载,下载地址

  IBM提供了DB2文档在线浏览FTP方式文档下载地址,下级目录包括各种翻译文档,也包括简体中文版(zh_CN),但某些文档只有英文版本,比如SQL说明书。

  DB210.1支持的操作平台有为Windows 32位/64位, Linux,Solaris、HP-UX 、AIX等。本次测试基于的运行环境是Intel Xeon E31270 3.4Ghz,内存4GB的PC服务器,物理CPU个数是1个,1TB SAS本地磁盘,采用一块 512M缓存 RAID卡,按RAID5方式组成磁盘阵列。操作系统采用Windows Server 2008 R2 简体中文标准版,这是一个只有x64平台的版本。为了充分发挥操作系统和硬件的能力,因此选用64位Windows版本安装文件,登录上述下载地址后选择“DB2 10.1 data server trial for Windows® on AMD64 and Intel® EM64T systems (x64)v10.1_ntx64_server.zip”下载,安装包尺寸大约854.6 MB,需解压缩到一个目录才能执行安装。下载速度较慢,用专门下载工具还用了40多小时,这对用户评估软件不利,建议IBM改善下载用户体验或者提供其他介质的测试软件。DB2在Windows操作系统的安装过程比较简单,因此本文简要地介绍一般安装步骤,专门指出易错的关键步骤。更详细的步骤,参考官方安装文档。简体中文版是上述FTP文档地址下的DB2InstallingServers-db2isc1010.pdf。

  安装步骤如下:

  1.安装前准备工作

  将下载的安装文件上传到待安装的机器,解压缩到某个目录,假定是“v10.1_ntx64_server\”,进入“SEEVER\image\”子目录,可以看到有个可执行的二进制文件“setup.exe”。双击执行此文件,就会出现DB2安装启动板界面,由于操作系统默认语言为简体中文,安装界面也是中文提示的,点击左侧导航栏“安装产品”即可开始安装。

数据库新品体验:IBM DB2 10.1首测
▲图1

  2.安装DB2数据库软件

  DB2用一个安装包包括了同一操作系统平台各个版本的功能,需要在安装时进行选择,我们这里选择高级企业版(Advanced Enterprise Server Edition)。

数据库新品体验:IBM DB2 10.1首测
▲图2

数据库新品体验:IBM DB2 10.1首测
▲图3

  需要注意,上述安装并不包括数据库管理客户端,客户端需要单独下载并安装,直接在安装启动板选择安装Data Studio组件是无效的。

  安装过程有几个步骤需要用户确认和选择,第一个需要选择的是安装类型,这里我们选择定制安装,这将允许安装所有的功能组件。

数据库新品体验:IBM DB2 10.1首测
▲图4

  然后在出现的安装功能组件界面,选择所有的组件。

数据库新品体验:IBM DB2 10.1首测
▲图5

${PageNumber}

  至于默认语言、SSH安装选项、都采取默认值即可。在此不一一列出。

数据库新品体验:IBM DB2 10.1首测
▲图6

  在选择副本名称时,可以采取默认值,也可以自己设定,公共应用程序的数据目录也可以按照需要指定。

数据库新品体验:IBM DB2 10.1首测
▲图7

  DB2管理服务器是管理一台机器上安装的多个DB2副本的,非常重要,这里我们为adb2admin用户输入密码也是adb2admin。在实际生产环境中,需要设置一个复杂的密码。

数据库新品体验:IBM DB2 10.1首测
▲图8

  在配置DB2实例时,检查是否在系统启动时自动启动实例。

数据库新品体验:IBM DB2 10.1首测
▲图9

  最后配置Db2的文本查找服务,也采用默认值。

数据库新品体验:IBM DB2 10.1首测
▲图10

  一切配置完成后,在总结页面点击“完成”按钮,即可开始软件的真正安装。当前设置在文本框中显示,可以用复制、粘贴的方法复制到文件保存,以便将来参考。

  在安装的同时,也自动在指定目录生成了响应文件,它记录了我们选择的所有配置信息。将来可以利用它来实现静默安装,响应文件的内容如下。其中几个用户密码是用加密方式存储的。

PROD=ADVANCED_ENTERPRISE_SERVER_EDITION
LIC_AGREEMENT
=ACCEPT
FILE
=C:\Program Files\IBM\SQLLIB\
INSTALL_TYPE
=CUSTOM


COMP
=ORACLE_DATA_SOURCE_SUPPORT
COMP
=DOTNET_DATA_PROVIDER

COMP
=JAVA_RUNTIME_SUPPORT
COMP
=JDBC_SUPPORT
COMP
=JDK
COMP
=LDAP_EXPLOITATION
COMP
=ODBC_SUPPORT
COMP
=OLE_DB_SUPPORT
COMP
=REPL_CLIENT
COMP
=DB2_SAMPLE_DATABASE
COMP
=SQLJ_SUPPORT
COMP
=SSH_SERVER
COMP
=TEXT_SEARCH
COMP
=WMI_PROVIDER


LANG
=EN
LANG
=CN

DAS_CONTACT_LIST
=LOCAL

DB2_DOCPORT
=51000

DB2_DOCHOST
=WIN-BR1K22K3MUC

INSTANCE
=DB2
DB2.NAME
=DB2
DEFAULT_INSTANCE
=DB2
DB2.SVCENAME
=db2c_DB2
DB2.DB2COMM
=TCPIP
...
DB2.PORT_NUMBER
=50000

DB2.AUTOSTART
=YES
DB2.USERNAME
=db2admin
DB2.PASSWORD
=44633322……
ENCRYPTED
=DB2.PASSWORD
DAS_USERNAME
=db2admin
DAS_PASSWORD
=23712018……
ENCRYPTED
=DAS_PASSWORD
CREATE_DAS
=YES
DB2_EXTSECURITY
=YES
DB2_USERSGROUP_NAME
=DB2USERS
DB2_ADMINGROUP_NAME
=DB2ADMNS
DB2_COMMON_APP_DATA_TOP_PATH
=C:\ProgramData
RSP_FILE_NAME
=C:\Users\Administrator\Documents\PROD_AESE.rsp
DB2_COPY_NAME
=DB2COPY1
DEFAULT_COPY
=YES
DEFAULT_CLIENT_INTERFACE_COPY
=YES

  安装完成后,安装程序给出如下的信息。我们就可以开始使用db2软件了。

数据库新品体验:IBM DB2 10.1首测
▲图11

${PageNumber}

  3.创建和访问数据库

数据库新品体验:IBM DB2 10.1首测
▲图12

  如果要尽快测试db2数据库的功能,可在第1步页面点击“创建样本数据库”按钮可以创建样本数据库,这一步骤比较耗时,大约十五分钟才能完成。Data Stduio软件需要单独安装,这里不赘述。我们的测试工作还是围绕命令行展开,需要注意,由于需要初始化一些环境变量,不能直接在Windows的cmd命令窗口转到db2命令行工具目录下执行命令,而需要利用db2安装的几个快捷方式执行db2命令行工具。如下图所示。

数据库新品体验:IBM DB2 10.1首测
▲图13

  如果选择“命令窗口”,就会自动运行“db2”命令,进入交互界面。因为此时环境已经初始化,也可以用quit命令退出交互界面,直接执行各种db2自带的命令。

数据库新品体验:IBM DB2 10.1首测
▲图14

  而“命令窗口 - 管理器”是执行某些数据库实例管理功能必需的,下文不久就会提到。

  至此,安装过程结束。

${PageNumber}

  二、DB2新功能简介

  1.DB2 10.1新功能和性能改进

  DB2 10 提供了众多增强功能,它们的直接效果就是更快的开箱即用查询性能,减少数据库管理员 (DBA) 的工作,以及在正常的系统和数据库更改之间实现更加一致且可重复的查询性能。

  (1)数据仓库类查询的增强

  包含哈希联接 (hash join) 的查询。在许多情况下,对包含联接的查询而言,哈希联接是最有效的联接策略,在 DB2 10 中,哈希联接可用于更多情形。查询优化器在联接谓词包含表达式时会自动考虑哈希联接,甚至在联接中的两列不是相同数据类型时也是如此。

  对星形模式的查询。星形模式性能改进包括改进的星形模式检测算法和新的联接方法。改进的算法使查询优化器能够检测基于星形模式设计的查询,使用合适的策略来改善这些查询的性能。也可以使用新的之字形联接方法来加快对基于星形模式设计查询的处理。

  (2)统计视图增强

  查询优化器使用统计视图来生成更好的访问计划。

  包含复杂表达式的谓词。查询优化器现在可使用来自统计视图中的表达式列(包含一个或多个函数的列)的统计信息来生成更好的访问计划。

  如果定义了参照完整性约束,现在星形联接查询要获得更好的统计数据,所需的统计视图更少。

  统计视图上的列组统计信息。将列组统计信息与统计视图相结合,可在某些情形下改进访问计划。

  DB2 自动统计集合函数现在可自动为统计视图收集统计数据。

  您可以设置某些注册表变量,在全局级别或语句级别对优化配置文件中的 SQL 编译器施加影响。优化配置文件还支持不准确匹配,这种匹配会在匹配语句时忽略文字、宿主变量 (host variable) 和参数标记。

  可以在 RUNSTATS 命令上指定新的 INDEXSAMPLE 选项,以使用一种采样方法有效地收集索引统计信息,而不用扫描整个索引。收集详细索引统计信息的默认方法也已更改为使用采样。当然,您仍然可以选择扫描整个索引来收集详细索引统计信息,就像在以前的版本中一样(只需指定 UNSAMPLED 子句即可)。

  (3)SQL兼容性增强

  如果您更熟悉其他关系数据库产品,DB2 10 包含的一些增强能够轻松实现与 DB2 产品协同工作。以下增强基于一组随以前的 DB2 for Linux, UNIX, and Windows 版本发布的 SQL 兼容性增强,减少了使一些应用程序在 DB2 环境中运行所需的时间和复杂性。

  更灵活且功能丰富的 CREATE TRIGGER 支持。触发器事件子句现在可包含多于一个的 INSERT、UPDATE 或 DELETE 操作,这意味着一个触发器可由指定事件的任何组合来激活。尽管可在单个 CREATE TRIGGER 语句中指定一个、两个或所有三个触发器事件,但一个触发器事件只能指定一次。您也可以使用在触发的操作中使用的新触发器事件谓词(INSERTING、UPDATING 和 DELETING)来测试激活触发器的事件。一个触发器事件谓词仅在编译的触发器定义的已触发操作中有效。最后,对于 PL/SQL 触发器,CREATE TRIGGER 语句中现在支持 FOR EACH STATEMENT 选项。您可以创建仅为每个语句触发一次的触发器。

  声明的用户定义数据类型和过程。现在可以声明位于一个复合 SQL(已编译的)语句本地的用户定义数据类型和过程。有关这些类型和过程的信息未存储在系统目录中。

  新的标量函数。INSTRB 函数返回另一个字符串中一个字符串的开始位置(以字节为单位)。TO_SINGLE_BYTE 函数返回一个字符串,其中的多字节字符会在可能时转换为等效的单字节字符。

  (4)连续数据摄入

  新的高速摄入实用工具INGEST将来自文件的数据以各种数据格式或通道传输到 DB2 表中。摄入操作很快,因为该实用工具拥有一种多线程架构,能够快速填充甚至分区数据库环境中的大型数据库。

  要了解更多db2 10新特性,请查看下面的ibm官方站点

  查询的执行计划改进主要在后台,而且没有相应老版本的db2作参照,不容易观察到,下面选择其他几个明显的新功能进行测试。

${PageNumber}

  2.新功能测试

  2.1 INGEST工具

  INGEST(摄入)实用工具是 DB2 10 提供的新功能,是为了有大量持续的数据流来实时和并发的快速进行数据导入而引入的新概念。它不会锁定目标表;它使用行锁定来最小化对同时处理同一个表的活动的影响。这样可以避免数据被锁,可以 24 小时对数据库进行操作。INGEST 有数据修复的功能,在数据导入中断时能找到中断点并能继续进行数据导入。

  INGEST 支持文件和管道两种输入类型,支持 DEL、ASC 两种数据格式,支持复杂的 SQL 表达式,支持 INSERT、UPDATE、MERGE、REPLACE 和 DELETE操作,支持并发更改,插入,删除,可以根据时间间隔或者数据条数来提交数据。可以指定要如何处理被摄入实用工具(使用 DUMPFILE 子句)或 DB2(使用 EXCEPTION TABLE 子句)拒绝的行。INGEST 会把未插入的数据放入文件,表或者直接丢弃,支持修复和重启。

  INGEST 支持 ESE,PureScale,DPF 环境。INGEST 与数据引擎使用标准化的外部接口,是个多线程工具,速度快,效率高。

  INGEST 支持很多种表,但不支持 AQT(accelerated query tables),CGTT/DGTT(created or declared global temporary tables,typed tables)和 typed views。同时,INGEST 不支持 LOB (BLOB, CLOB, DBCLOB), XML, structured types 这些数据类型和基于这些的自定义数据类型。

  INGEST 工具有以下相关的命令:

  •INGEST 来进行数据导入,最简单的语法结构是:

  INGEST from FILE 或 PIPE format 子句INTO TABLE

  其他的命令还包括:

  •INGEST LIST 来显示当前的 INGEST 进程信息。

  •INGEST GET STATS 来得到当前的 INGEST 状态统计信息。

  •INGEST SET 来设置 INGEST 的一些参数

  连续数据摄入功能可在 Advanced Enterprise Server Edition 中找到。

  首先介绍ingest工具的配置,由于不熟悉这个新工具,我的测试过程走了很多弯路,因此为了帮助读者尽快能使用这个工具,也把问题的原因和解决步骤列出来。

  要成功利用INGEST工具、必须具备2个前提条件,第一、必须存在所需的日志表,用于存储关于ingest作业的信息。第二、必须有访问磁盘文件的权限。

  如果在普通的db2命令行就会报访问介质失败错误。这说明对磁盘文件没有权限。

C:\Program Files\IBM\SQLLIB\BIN>db2 "INGEST FROM FILE nation.tbl FORMAT DELIMITED by '|' INSERT INTO tpch.nation2"
SQL2061N  尝试访问介质
"" 被拒绝。
SQL2902I  摄取实用程序已完成,时间戳记为
"2012-07-12
18:37:10.857629
"。错误数:"1"。警告数:"0"

  进入管理员方式的db2命令行。再次运行ingest就具有了访问磁盘文件的权限。

C:\Program Files\IBM\SQLLIB\BIN>db2 connect to tpch

   数据库连接信息

数据库服务器        
= DB2/NT64 10.1.0
SQL 授权标识        
= DB2ADMIN
本地数据库别名      
= TPCH

  如果没有创建日志表,会报以下错误信息。

C:\Program Files\IBM\SQLLIB\BIN>db2 INGEST FROM FILE nation.tbl FORMAT DELIMITED INSERT INTO tpch.nation2
SQL2957N  Ingest 实用程序找不到重新启动日志表
"SYSTOOLS.INGESTRESTART"
SQLSTATE
=42704
SQL2902I  摄取实用程序已完成,时间戳记为
"2012-07-18
21:54:42.372941"。错误数:"1"。警告数:"0"

  利用下面存储过程创建日志表。

db2 => CALL SYSPROC.SYSINSTALLOBJECTS('INGEST','C',CAST (NULL AS VARCHAR(128)),CAST (NULL AS VARCHAR(128)))

  返回状态
= 0

  再次运行刚才的命令,就能够执行下去,不过这次是报文件格式化错误,这是因为ingest工具默认的分隔符是“,”,而tpch的数据文件分隔符是“|”。

db2 => INGEST FROM FILE nation.tbl FORMAT DELIMITED INSERT INTO tpch.nation2
SQL2979I  Ingest 实用程序正在启动,时间戳记为
"2012-07-19 21:18:42.784464"
SQL2914I  Ingest 实用程序已启动以下 Ingest
作业:
"DB21001:20120719.211842.784464:00002:00012"
SQL2922I  格式化输入文件
"nation.tbl" 的第 "1"
行中的数据时产生了以下警告或错误。
SQL2927N  无法将第
"1" 行的 "1" 字段中的字段值转换为以下值类型:"INTEGER"

读取行数        
= 25
插入行数        
= 0
拒绝行数        
= 25

SQL2902I  摄取实用程序已完成,时间戳记为
"2012-07-19
21:18:43.902493
"。错误数:"25"。警告数:"0"

  还有一个陷阱必须引起注意,就是代码页问题,在中文环境中,假如不设置代码页,即使用正确的分隔符也是不能导入的。

db2 => INGEST FROM FILE nation.tbl FORMAT DELIMITED by '|' INSERT INTO tpch.nation2
SQL3017N  定界符无效,或使用多次。
SQL2902I  摄取实用程序已完成,时间戳记为
"2012-07-19
21:19:25.582240
"。错误数:"1"。警告数:"0"

  错误提示信息并未提到代码页问题,容易使人联想到是否最后一个“|”分隔符造成了这个错误,于是通过filler字段跳过,但结果证明也不是这个原因。

db2 => INGEST FROM FILE nation.tbl FORMAT DELIMITED by X'7C' ($f1 char(25),$f2 CHAR(25) ,$f3 char(25) ,$f4 CHAR(152),$fi
ller1 char
)INSERT INTO tpch.nation2 values($f1,$f2,$f3,$f4)
SQL3017N  定界符无效,或使用多次。
SQL2902I  摄取实用程序已完成,时间戳记为
"2012-07-19
21:50:12.439694
"。错误数:"1"。警告数:"0"

  再把数据文件分隔符修改成默认分隔符“,”,这次导入成功了。

C:\Program Files\IBM\SQLLIB\BIN>type nation4.tbl
0,ALGERIA,0, haggle. carefully final deposits detect slyly agai
1,ARGENTINA,1,al foxes promise slyly according to the regular accounts. bold requests alon
2,BRAZIL,1,y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special

C:
\Program Files\IBM\SQLLIB\BIN>db2 INGEST FROM FILE nation4.tbl FORMAT DELIMITED INSERT INTO tpch.nation2
SQL2979I  Ingest 实用程序正在启动,时间戳记为
"2012-07-20 06:32:55.014255"
SQL2914I  Ingest 实用程序已启动以下 Ingest
作业:
"DB21001:20120720.063255.014255:00002:00012"

插入行数        
= 3

SQL2980I  Ingest 实用程序已成功完成,时间戳记为
"2012-07-20 06:32:56.069637"

  参阅db2信息中心上的文档,可以发现下面一段关于ingest分隔符要求的描述:

  “If the input data code page is a DBCS or EUC code page, the character must be in the range X'01' to X'3F', inclusive. Note that this excludes the vertical bar (| or X'7C'). If the input data code page is not a single-byte code page, the character must be in the range X'01' to X'7F', inclusive. If the input code page is a single-byte code page, the character can be in the range X'01' to X'FF'. ”,它是说外部输入数据的代码页决定了可以使用的分隔符,如果是双字节或多字节的代码页,那么“|”(X'7C')不在可选的分隔符范围内。但我们知道tpch数据文件是单字节字符集,为什么还会出现这种现象?这就和客户端的代码页有关。中文系统的客户端代码页和数据库是不同的。

  使用db2set db2codepage命令将客户端代码页设成和数据库一致,由于创建数据库时采用的字符集是UTF-8,所以查表可知,代码页是1208,设置代码页后断开现有连接,再重新连接数据库。这回分隔符为“|”的数据文件也成功地导入了。

C:\Program Files\IBM\SQLLIB\BIN>db2set db2codepage=1208

C:
\Program Files\IBM\SQLLIB\BIN>db2 terminate
DB20000I  TERMINATE 命令成功完成。

C:
\Program Files\IBM\SQLLIB\BIN>db2 connect to tpch

C:
\Program Files\IBM\SQLLIB\BIN>type nation2.tbl
0|ALGERIA|0| haggle. carefully final deposits detect slyly agai
1|ARGENTINA|1|al foxes promise slyly according to the regular accounts. bold requests alon
2|BRAZIL|1|y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special

C:
\Program Files\IBM\SQLLIB\BIN>db2 INGEST FROM FILE nation2.tbl FORMAT DELIMITED by x'7c' INSERT INTO tpch.nation2
SQL2979I  Ingest 实用程序正在启动,时间戳记为
"2012-07-20 18:29:09.812696"

插入行数        
= 3

SQL2980I  Ingest 实用程序已成功完成,时间戳记为
"2012-07-20 18:29:10.856827"

  最后还要留意,由于“|”字符是操作系统管道符,如果在Db2交互命令行环境中使用是没有问题的,如果在操作系统命令行就不能使用,而必须用X'07'来代替,否则会造成下面的奇怪错误。

C:\Program Files\IBM\SQLLIB\BIN>db2 INGEST FROM FILE nation2.tbl FORMAT DELIMITED by '|' INSERT INTO tpch.nation2
''' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
C:
\Program Files\IBM\SQLLIB\BIN>db2 truncate table tpch.customer2
DB20000I  SQL 命令成功完成。

  ingest工具配置成功后,下面来测试它的各项功能。

  (1)从多个文件插入用时32秒,这里的数据文件通过tpch的dbgen -s 10 -T c -C -S 1(以及2,3,4)命令行产生,表结构参见TPCH测试的第2部分。

C:\Program Files\IBM\SQLLIB\BIN>db2 INGEST FROM FILE C:\Users\db2admin\customer.tbl.1,C:\Users\db2admin\customer.tbl.2,C:\Users\db2admin\customer.tbl.3,C:\Users\db2admin\customer.tbl.4 FORMAT DELIMITED by x'7c' INSERT INTO tpch.customer2
SQL2979I  Ingest 实用程序正在启动,时间戳记为
"2012-07-21 07:18:10.009589"

插入行数        
= 1500000

SQL2980I  Ingest 实用程序已成功完成,时间戳记为
"2012-07-21 07:18:42.025524"

C:
\Program Files\IBM\SQLLIB\BIN>db2 truncate table tpch.customer2
DB20000I  SQL 命令成功完成。

  而直接对包含同样数据的一个文件的插入大约23秒。可见多文件插入没有性能优势。

C:\Program Files\IBM\SQLLIB\BIN>db2 INGEST FROM FILE C:\Users\db2admin\customer.tbl FORMAT DELIMITED by x'7c' INSERT INTO tpch.customer2
SQL2979I  Ingest 实用程序正在启动,时间戳记为
"2012-07-21 07:19:16.496681"

插入行数        
= 1500000

SQL2980I  Ingest 实用程序已成功完成,时间戳记为
"2012-07-21 07:19:39.416443"

  利用ingest实现数据更新的测试,创建测试表并导入数据文件中的数据:

SQL> CREATE TABLE tpch.NATION2 ( N_NATIONKEY INTEGER NOT NULL, N_NAME CHAR(25) NOT NULL, N_REGIONKEY INTEGER NOT NULL, N
_COMMENT VARCHAR
(152));

DB250000I: 成功地完成该命令。

耗用时间为:
500 毫秒
SQL
> INGEST FROM FILE nation4.tbl FORMAT DELIMITED by x'7c' INSERT INTO tpch.nation2;
1 行附近出现错误:
SQL0104N  在
"INGEST FROM " 后面找到异常标记 "FILE"。预期标记可能包括:"JOIN"
SQL
> exit

C:
\Program Files\IBM\SQLLIB\BIN>db2 INGEST FROM FILE nation2.tbl FORMAT DELIMITED by x'7c' INSERT INTO tpch.nation2
SQL2979I  Ingest 实用程序正在启动,时间戳记为
"2012-07-22 20:38:18.048493"

插入行数        
= 3

SQL2980I  Ingest 实用程序已成功完成,时间戳记为
"2012-07-22 20:38:19.012839"

C:
\Program Files\IBM\SQLLIB\BIN>db2 select N_NATIONKEY,N_NAME, N_REGIONKEY from tpch.nation2

N_NATIONKEY N_NAME                    N_REGIONKEY
----------- ------------------------- -----------
          
0 ALGERIA                             0
          
1 ARGENTINA                           1
          
2 BRAZIL                              1

  为了验证更新效果,首先将2列数据更新为无意义的常数。

C:\Program Files\IBM\SQLLIB\BIN>db2 update tpch.nation2 set N_NAME='oldname', N_REGIONKEY=-1
DB20000I  SQL 命令成功完成。

C:
\Program Files\IBM\SQLLIB\BIN>db2 select N_NATIONKEY,N_NAME, N_REGIONKEY from tpch.nation2

N_NATIONKEY N_NAME                    N_REGIONKEY
----------- ------------------------- -----------
          
0 oldname                            -1
          
1 oldname                            -1
          
2 oldname                            -1

  编辑带有更新(update)语句的ingest命令到一个文件,注意以分号结束命令,整数类型要用INTEGER EXTERNAL关键字,varchar类型改为char类型。

C:\Program Files\IBM\SQLLIB\BIN>type ingest_upd.txt
INGEST FROM FILE nation2
.tbl
        
FORMAT DELIMITED by x'7c'
        
(
                
$key1 INTEGER EXTERNAL,
                
$data1 CHAR(25),
                
$data2 INTEGER EXTERNAL,
                
$data3 CHAR(152)
        
)
        UPDATE tpch
.nation2
                
SET (N_NAME, N_REGIONKEY) = ($data1, $data2)
                WHERE
(N_NATIONKEY = $key1) ;

  执行ingest命令后,选择数据被更新为数据文件中的内容。

C:\Program Files\IBM\SQLLIB\BIN>db2 -tvf ingest_upd.txt
INGEST FROM FILE nation2
.tbl FORMAT DELIMITED by x'7c' ( $key1 INTEGER EXTERNAL, $data1 CHAR(25), $data2 INTEGER EXTERNAL, $data3 CHAR(152) ) UPDATE tpch.nation2 SET (N_NAME, N_REGIONKEY) = ($data1, $data2) WHERE (N_NATIONKEY = $key1)
SQL2903W  已经将配置参数
"NUM_FLUSHERS_PER_PARTITION"
自动调整为以下值:
"1"。原因码为 "12"
SQL2979I  Ingest 实用程序正在启动,时间戳记为
"2012-07-22 20:43:26.660890"

读取行数        
= 3
更新行数        
= 3
拒绝行数        
= 0

SQL2902I  摄取实用程序已完成,时间戳记为
"2012-07-22
20:43:27.772538
"。错误数:"0"。警告数:"1"

C:
\Program Files\IBM\SQLLIB\BIN>db2 select N_NATIONKEY,N_NAME, N_REGIONKEY from tpch.nation2

N_NATIONKEY N_NAME                    N_REGIONKEY
----------- ------------------------- -----------
          
0 ALGERIA                             0
          
1 ARGENTINA                           1
          
2 BRAZIL                              1

  
3 条记录已选择。
${PageNumber}

  2.2兼容Oracle的功能测试

  这是为了熟悉Oracle的用户向db2迁移而设计的功能,10.1版宣称可以做到98%的代码不需要修改就能在db2中运行原来的Oracle应用,但实际效果还是要亲自使用才知道。

  设置步骤如下:

  首先要用db2set命令在注册变量中设定兼容模式,然后重新启动实例,再发出create database命令,如果在db2set设定前创建的数据库,则不能完全用到db2兼容Oracle的功能,因为兼容不但需要提供模拟Oracle的命令,还需要创建一系列系统表,比如类似Oracle的dict等数据字典表。兼容oracle的数据库可以用到oracle的一些特有的命令,比如connect by语法。

  虽然在Windows环境中启用兼容oracle模式与Linux环境大同小异,但有一些值得注意之处,因此下面还是完整描述一遍启用过程,以方便读者重复这一设置。

  db2set在普通的DB2命令行窗口中输入命令会报错:

C:\Program Files\IBM\SQLLIB\BIN>db2set db2_compatibility_vector=ora
DB21009E  必须在命令窗口中以完整管理特权运行才能启动此命令。

  切换到DB2管理员命令行窗口(即安装部分提到的“命令窗口 - 管理器”)中输入命令即可:

C:\Program Files\IBM\SQLLIB\BIN>db2set db2_compatibility_vector=ora

  查看当前设置可看到DB2_COMPATIBILITY_VECTOR参数已被设置为ORA:

C:\Program Files\IBM\SQLLIB\BIN>db2set
DB2_ATS_ENABLE
=YES
DB2_COMPATIBILITY_VECTOR
=ORA
DB2INSTOWNER
=WIN-BR1K22K3MUC
DB2PORTRANGE
=60000:60003
DB2INSTPROF
=C:\PROGRAMDATA\IBM\DB2\DB2COPY1
DB2COMM
=TCPIP

  关闭和启动实例也需要在DB2管理员命令行窗口中输入命令:

C:\Program Files\IBM\SQLLIB\BIN>db2stop force
2012-07-12 20:09:13     0   0   SQL1064N  DB2STOP 处理成功。
SQL1064N  DB2STOP 处理成功。

C:
\Program Files\IBM\SQLLIB\BIN>db2start
2012-07-12 20:09:27     0   0   SQL1063N  DB2START 处理成功。
SQL1063N  DB2START 处理成功。

  删除和创建数据库可以在普通的DB2命令行窗口中输入命令:

C:\Program Files\IBM\SQLLIB\BIN>db2 drop database orcl
SQL1035N  数据库当前正在使用。  SQLSTATE
=57019

  先断开需要删除的数据库:

C:\Program Files\IBM\SQLLIB\BIN>db2 terminate
DB20000I  TERMINATE 命令成功完成。

C:
\Program Files\IBM\SQLLIB\BIN>db2 drop database orcl
DB20000I  DROP DATABASE 命令成功完成。

C:
\Program Files\IBM\SQLLIB\BIN>db2 "create database orcl using CODESET UTF-8 TERRiTORY CN pagesize 32 K"
DB20000I  CREATE DATABASE 命令成功完成。

  clpplus是基于Java的应用程序,必须指定Java程序位置才能执行,尽量把Java位置放到搜索路径的开头。

C:\Program Files\IBM\SQLLIB\BIN>clpplus -nw db2admin/db2admin@localhost:60000/orcl
CLPPlus requires Java
1.5 or higher to execute.
Please ensure Java is in your
PATH.
C:
\Program Files\IBM\SQLLIB\BIN>set path=C:\Progra~1\IBM\SQLLIB\java\jdk\bin;%path%

C:
\Program Files\IBM\SQLLIB\BIN>clpplus -nw db2admin/db2admin@localhost:60000/orcl
CLPPlus: 版本
1.5
Copyright ?
2009, 2011, IBM CORPORATION.  All rights reserved.

[jcc][t4][
2043][11550][3.63.123] 异常 java.net.ConnectException:打开端口 60,000 上服务器 localhost/127.0.0.1 的套接字时
出错,消息为:Connection refused: connect。 ERRORCODE
=-4499, SQLSTATE=08001

  把端口改为50000则可以连接,这点与Linux下不同,需要格外注意:

C:\Program Files\IBM\SQLLIB\BIN>clpplus -nw db2admin/db2admin@localhost:50000/tpch
CLPPlus: 版本
1.5
Copyright ?
2009, 2011, IBM CORPORATION.  All rights reserved.

  因为TPCH数据库不是在设置Oracle兼容模式后创建的,所以不存在兼容数据字典视图。

SQL> select tname from tab;
1 行附近出现错误:
SQL0204N  
"DB2ADMIN.TAB" 是一个未定义的名称。
SQL
> exit

C:
\Program Files\IBM\SQLLIB\BIN>clpplus -nw db2admin/db2admin@localhost:50000/orcl
CLPPlus: 版本
1.5
Copyright ?
2009, 2011, IBM CORPORATION.  All rights reserved.

  orcl数据库是在设置Oracle兼容模式后创建的,所以存在兼容数据字典视图:

SQL> select tname from tab;

TNAME
--------------------------------------------------
POLICY
HMON_ATM_INFO
HMON_COLLECTION

SQL
> set serverout on

  以上配置过程主要是某些命令需要用管理员命令行执行和连接端口不同。

  下面测试两项10.1新功能:

  第一、允许在匿名PL/SQL块中定义类型

SQL> DECLARE
  2    TYPE point IS RECORD(x NUMBER, y NUMBER);
  
3    here point;
  4    BEGIN
  
5    here := (5, 3);
  
6    dbms_output.put_line(here.x);
  
7    dbms_output.put_line(here.y);
  
8    END;
  
9  /
5
3

DB250000I: 成功地完成该命令。

  第二、允许在匿名PL/SQL块中定义存储过程

SQL> DECLARE
  
2    TYPE point IS RECORD(x NUMBER, y NUMBER);
  3    PROCEDURE makepoint(x IN NUMBER, y IN NUMBER, xy OUT point)
  
4    IS
  
5    BEGIN
  
6    xy := (x, y);
  
7    END;
  8    here point;
  
9    BEGIN
10    makepoint(5, 3, here);
11    dbms_output.put_line(here.x);
12    dbms_output.put_line(here.y);
13    END;
14  /
5
3

DB250000I: 成功地完成该命令。

  Db2 10仍然不支持某些Oracle的命令格式,如connect by rownum和level语法,使用了这种命令的SQL必须改写为递归子查询。后者性能与connect by相当。

SQL> set timi on
SQL
> select sum(x) from (select level x from dual connect by level<=1e6);
1 行附近出现错误:
SQL20451N  在分层查询中检测到了循环。
SQL
> select sum(x) from (select level x from dual connect by rownum<=1e6);
1 行附近出现错误:
SQL0120N  无效使用了聚集函数或 OLAP 函数。
SQL
> with t(x) as
  
2  (select cast (1 as number(10,0)) x from dual
  
3  union all
  
4  select x+1 x from t where x<1e6)
  
5  select sum(x) from t;

                                        
1
------------------------------------------
                              
500000500000

DB250000I: 成功地完成该命令。

耗用时间为:
3433 毫秒

  个人认为对查询语句计时是clpplus最值得使用的功能之一,在SQL调优过程中使用十分方便,不知道db2为何不在clp工具中同样实现它。

SQL> set timi on
SQL
> select sysdate from dual;

1
---------------------
2012-07-21 19:33:39
耗用时间为:
94 毫秒

  desc命令查看表结构也比查询数据字典方便很多:

SQL> desc tpch.nation

TABLE - NATION
********************************************************************************

名称                 数据类型       类型模式       长度     小数位  null 隐藏
------------------- ------------- ------------- -------- ------- ----- --------
N_NATIONKEY         INTEGER       SYSIBM              
4       0 N     Not
N_NAME              CHARACTER     SYSIBM              
25       0 N     Not
N_REGIONKEY         INTEGER       SYSIBM              
4       0 N     Not
N_COMMENT           VARCHAR       SYSIBM            
152       0 Y     Not

********************************************************************************

  查看执行计划,创建索引前,执行计划是表扫描:

SQL> explain plan for select count(*) cnt from tpch.part where p_size=30;

    ID
TYPE            OBJECT_SCHEMA        OBJECT_NAME          PREDICATE_TEXT
------ --------------- -------------------- -------------------- -----------------------
    
1 RETURN
    
2 GRPBY
    
3 TBSCAN          TPCH                 PART                 (Q1.P_SIZE = 30)

  创建索引后,执行计划变成了索引扫描:

SQL> create index tpch.part_size_idx on tpch.part(p_size);

DB250000I: 成功地完成该命令。

耗用时间为:
5758 毫秒
SQL
> explain plan for select count(*) cnt from tpch.part where p_size=30;

    ID
TYPE            OBJECT_SCHEMA        OBJECT_NAME          PREDICATE_TEXT
------ --------------- -------------------- -------------------- -----------------------
    
1 RETURN
    
2 GRPBY
    
3 IXSCAN          TPCH                 PART_SIZE_IDX        (Q1.P_SIZE = 30)
    
3 IXSCAN          TPCH                 PART_SIZE_IDX        (Q1.P_SIZE = 30)

  执行计划中出现了2行id为3的操作,这不知道是有特定的含义还是一个BUG。9.7版也有同样的问题。感觉与Oracle的计划显示还是有很大区别。

  同时,这个执行计划的输出速度较慢,它是先执行SQL查询,再输出计划,要对用时较长的查询快速输出执行计划,还应采用db2expln工具。

  作为与Oracle的sqlplus兼容的clpplus工具也得到了增强,9.7版本clpplus中只能输入SQL语句,PL/SQL语句和clpplus命令,不能输入db2的命令,比如runstats,10.1版已经可以支持。但工具本身也存在一些问题,比如将代码粘贴到clpplus命令行时,有时候会丢失字符,必须多加小心。关于clpplus命令最新的信息,可参考在线web页面文档

  最后还有个问题不得不提,不加-nw的clpplus命令其实也是文本方式,但却远不如加了-nw的效果,表现在如下几点,其一,默认字体是比例字体而不是等宽的,且不支持修改字体,导致表格文字不能对齐,请见图。其二,文本复制采取选中复制,右键粘贴的方式,容易造成误操作,如果是像drop table abc;这样的命令,实际是很危险的。其三启动相对缓慢。个人建议不使用不加-nw的clpplus命令。

IBM DB2 10.1首测:新功能简介

${PageNumber}

  2.3自适应压缩

  自适应压缩是对 DB2 压缩技术的一项显著增强。自适应压缩是一种先进的行压缩技术,它使用两种压缩字典类型(表级别和新页面级别字典)来改进压缩率,尤其是在数据更改时。当然,更高的压缩率会转化为 I/O 受限的系统和数据库备份操作的性能改进,以及更高的存储节省,但使用自适应压缩的一个额外的好处是,您无需执行显式表重组即可保持这些高压缩率。页面级压缩字典是自动创建的,如果一个页面的内容发生重大变化,页面级压缩字典会自动重新创建。当一个页面装满时,会应用页面级压缩,这样会迅速释放该页面上的更多存储空间。

  自适应压缩是这些启用行压缩的新表的默认行为。您可以为现有的表启用自适应压缩,只需使用 ALTER TABLE 语句以及 COMPRESS YES 子句或新的 COMPRESS YES ADAPTIVE 子句。为一个现有表启用了自适应压缩之后,所有后续更新或新添加的数据都会进行压缩。要向表中已存在的数据应用自适应压缩,只需执行一次表重组。

  自适应压缩可在Enterprise Server Edition 的存储优化功能 (SOF) 中找到,SOF 包含在 Advanced Enterprise Server Edition 中。

  db2 10.1现在的默认行压缩模式是ADAPTIVE,而如果需要恢复9.7版本的行压缩模式,则需要明确指定STATIC模式。

  用clpplus连接,可以方便计时以及输入多行SQL语句。我们同时设置行最大宽度和一页的行数。注意这些设置命令必须分行书写。

C:\Program Files\IBM\SQLLIB\BIN>set path=C:\Progra~1\IBM\SQLLIB\java\jdk\bin;%path%

C:
\Program Files\IBM\SQLLIB\BIN>clpplus -nw db2admin/db2admin@localhost:50000/orcl

SQL
> set timi on
SQL
> set lines 120
SQL
> set pages 50000

  用下面的语句检查当前压缩和估算不用压缩方法的压缩比,数字越大表示压缩后节约空间越多。

SQL> SELECT SUBSTR(TABNAME,1,20) AS TABNAME,
  
2         PCTPAGESSAVED_CURRENT,
  
3         PCTPAGESSAVED_STATIC,
  
4         PCTPAGESSAVED_ADAPTIVE
  
5  FROM TABLE(SYSPROC.ADMIN_GET_TAB_COMPRESS_INFO('TPCH',NULL));

TABNAME              PCTPAGESSAVED_CURRENT PCTPAGESSAVED_STATIC PCTPAGESSAVED_ADAPTIVE
-------------------- --------------------- -------------------- ----------------------
CUSTOMER                                
0                   45                     45
CUSTOMER2                                
0                   46                     46
LINEITEM                                
0                   61                     61
NATION                                  
0                   53                     53
ORDERS                                  
0                   59                     59
PART                                    
0                   66                     66
PARTSUPP                                
0                   65                     65
REGION                                  
0                   42                     42
SUPPLIER                                
0                   45                     45

检索到
9 行。

耗用时间为:
49172 毫秒

  由上述结果可知,tpch数据表预计压缩比最小的节约42%,最大的节约66%。STATIC和ADAPTIVE模式的压缩比相同,这个命令执行时间较长。

  用下面的语句检查当前是否压缩和压缩模式(如果压缩):

SQL> SELECT SUBSTR(TABSCHEMA, 1, 10) AS TABSCHEMA,
  
2         SUBSTR(TABNAME, 1, 20) AS TABNAME,
  
3         COMPRESSION, ROWCOMPMODE
  
4  FROM SYSCAT.TABLES
  
5  WHERE TABSCHEMA ='TPCH';

TABSCHEMA  TABNAME              COMPRESSION ROWCOMPMODE
---------- -------------------- ----------- -----------
TPCH       CUSTOMER             N
TPCH       CUSTOMER2            N
TPCH       LINEITEM             N
TPCH       NATION               N
TPCH       ORDERS               N
TPCH       PART                 N
TPCH       PARTSUPP             N
TPCH       REGION               N
TPCH       SUPPLIER             N

检索到
9 行。

耗用时间为:
111 毫秒

  由上述结果可知,各个表均没有压缩,这个命令执行时间很短。

  查看表占用空间, CUSTOMER2和CUSTOMER的原始大小是一样的。

SQL> select npages*32 , cast(tabname as varchar(20)) from syscat.tables where TABSCHEMA='TPCH';

                  
1 2
-------------------- --------------------
              
262304 CUSTOMER
              
262304 CUSTOMER2

  将tpch.CUSTOMER2改为压缩表,默认是行压缩,ADAPTIVE模式。

SQL> alter table tpch.CUSTOMER2 compress yes;

DB250000I: 成功地完成该命令。

耗用时间为:
235 毫秒

  对表进行重组执行已有数据的压缩。

SQL> reorg table tpch.customer2 resetdictionary;
DB250000I: 成功地完成该命令。

  收集统计信息:

SQL> RUNSTATS ON TABLE tpch.customer2 WITH DISTRIBUTION AND INDEXES ALL;
DB250000I: 成功地完成该命令。

  再次查看表占用空间, CUSTOMER2只有145920,节约了116384KB。

SQL> select npages*32 , cast(tabname as varchar(20)) from syscat.tables where TABSCHEMA='TPCH';

                  
1 2
-------------------- --------------------
              
262304 CUSTOMER
              
145920 CUSTOMER2

  表tpch.CUSTOMER2压缩后节约了44%的空间,与预计的46%很接近,可见预计比较准确。这次由于计算了实际压缩比,所以运行时间更长了。

SQL> SELECT SUBSTR(TABNAME,1,20) AS TABNAME,
  
2         PCTPAGESSAVED_CURRENT,
  
3         PCTPAGESSAVED_STATIC,
  
4         PCTPAGESSAVED_ADAPTIVE
  
5  FROM TABLE(SYSPROC.ADMIN_GET_TAB_COMPRESS_INFO('TPCH',NULL));

TABNAME              PCTPAGESSAVED_CURRENT PCTPAGESSAVED_STATIC PCTPAGESSAVED_ADAPTIVE
-------------------- --------------------- -------------------- ----------------------
CUSTOMER                                
0                   45                     45
CUSTOMER2                              
44                   46                     46

检索到
9 行。

耗用时间为:
55335 毫秒

  现在显示CUSTOMER2表的压缩类型为行压缩,压缩模式为ADAPTIVE。

SQL> SELECT SUBSTR(TABSCHEMA, 1, 10) AS TABSCHEMA,
  
2         SUBSTR(TABNAME, 1, 20) AS TABNAME,
  
3         COMPRESSION, ROWCOMPMODE
  
4  FROM SYSCAT.TABLES
  
5  WHERE TABSCHEMA ='TPCH';

TABSCHEMA  TABNAME              COMPRESSION ROWCOMPMODE
---------- -------------------- ----------- -----------
TPCH       CUSTOMER             N
TPCH       CUSTOMER2            R           A

  将压缩模式改为行压缩的STATIC,压缩比没有变化。这是因为我们通过重组对表中已有数据做了压缩,如果不重组,只有新插入或更新的行才会压缩,其他已有数据不会压缩。这也符合刚才查询语句的估算结果。

SQL> alter table tpch.CUSTOMER2 compress yes static;

DB250000I: 成功地完成该命令。

耗用时间为:
47 毫秒
SQL
> reorg table tpch.customer2 resetdictionary;
DB250000I: 成功地完成该命令。
SQL
> SELECT SUBSTR(TABSCHEMA, 1, 10) AS TABSCHEMA,
  
2         SUBSTR(TABNAME, 1, 20) AS TABNAME,
  
3         COMPRESSION, ROWCOMPMODE
  
4  FROM SYSCAT.TABLES
  
5  WHERE TABSCHEMA ='TPCH';

TABSCHEMA  TABNAME              COMPRESSION ROWCOMPMODE
---------- -------------------- ----------- -----------
TPCH       CUSTOMER             N
TPCH       CUSTOMER2            R           S

SQL
> RUNSTATS ON TABLE tpch.customer2 WITH DISTRIBUTION AND INDEXES ALL;
DB250000I: 成功地完成该命令。
SQL
> select npages*32 , cast(tabname as varchar(20)) from syscat.tables where TABSCHEMA='TPCH';

                  
1 2
-------------------- --------------------
              
262304 CUSTOMER
              
145920 CUSTOMER2

  值压缩是另一种行压缩的格式,主要用于空值(NULL)、默认值和变长数据类型(如varchar、CLOB)中的0长度数据的压缩。也称作空值和默认值压缩(NULL and default value compression)。

  再创建一个tpch.customer3表准备用于值压缩。

SQL> create table tpch.customer3 like tpch.customer;

DB250000I: 成功地完成该命令。

耗用时间为:
360 毫秒

  用insert select命令插入失败,报事务日志已满错误。将LOGFILSIZ参数改大也不能解决。

SQL> insert into tpch.customer3 select * from tpch.customer;
1 行附近出现错误:
SQL0964C  数据库的事务日志已满。

  改用INGEST方式插入数据,顺便将tpch.customer2截断,比较压缩表和普通表的插入性能。

SQL> truncate table  tpch.customer2;

DB250000I: 成功地完成该命令。

耗用时间为:
235 毫秒
SQL
> exit

  压缩表的插入时间是13秒:

C:\Program Files\IBM\SQLLIB\BIN>db2 INGEST FROM FILE C:\Users\db2admin\customer.tbl FORMAT DELIMITED by x'7c' INSERT INTO tpch.customer2
SQL2979I  Ingest 实用程序正在启动,时间戳记为
"2012-07-22 10:39:26.557221"

插入行数        
= 1500000

SQL2980I  Ingest 实用程序已成功完成,时间戳记为
"2012-07-22 10:39:39.923511"

  普通表的插入时间是32秒,压缩表的加载时间大大短于普通表,约是后者的40%。

C:\Program Files\IBM\SQLLIB\BIN>db2 INGEST FROM FILE C:\Users\db2admin\customer.tbl FORMAT DELIMITED by x'7c' INSERT INTO tpch.customer3
SQL2979I  Ingest 实用程序正在启动,时间戳记为
"2012-07-22 10:39:53.404114"

插入行数        
= 1500000

SQL2980I  Ingest 实用程序已成功完成,时间戳记为
"2012-07-22 10:40:25.172662"

  收集统计信息并重新检查空间占用情况:

C:\Program Files\IBM\SQLLIB\BIN>clpplus -nw db2admin/db2admin@localhost:50000/orcl
SQL
> RUNSTATS ON TABLE tpch.customer2 WITH DISTRIBUTION AND INDEXES ALL;
DB250000I: 成功地完成该命令。
SQL
> RUNSTATS ON TABLE tpch.customer3 WITH DISTRIBUTION AND INDEXES ALL;
DB250000I: 成功地完成该命令。

  tpch.customer2已经是压缩类型,ingest导入后的空间占用和前面用表重组方式是一样的。tpch.customer3的空间占用比CUSTOMER略小,基本是相同的。

SQL> select npages*32 , cast(tabname as varchar(20)) from syscat.tables where TABSCHEMA='TPCH';

                  
1 2
-------------------- --------------------
              
262304 CUSTOMER
              
145920 CUSTOMER2
              
262016 CUSTOMER3

检索到
10 行。

耗用时间为:
17 毫秒

  对CUSTOMER3表启用值压缩并重组。

SQL> ALTER TABLE tpch.customer3 ACTIVATE VALUE COMPRESSION ;

DB250000I: 成功地完成该命令。

耗用时间为:
47 毫秒
SQL
> reorg table tpch.customer3 resetdictionary
  
2  ;
DB250000I: 成功地完成该命令。
SQL
> RUNSTATS ON TABLE tpch.customer3 WITH DISTRIBUTION AND INDEXES ALL;
DB250000I: 成功地完成该命令。

  压缩后,CUSTOMER3占用的空间反而超过了压缩前,这是因为表中没有空值,无法压缩。而压缩格式比普通格式还增加了字典表的开销。

SQL> select npages*32 , cast(tabname as varchar(20)) from syscat.tables where TABSCHEMA='TPCH';

                  
1 2
-------------------- --------------------
              
262304 CUSTOMER
              
145920 CUSTOMER2
              
271168 CUSTOMER3

  以下查询确认CUSTOMER3确实是值压缩类型:

SQL> SELECT SUBSTR(TABSCHEMA, 1, 10) AS TABSCHEMA,
  
2         SUBSTR(TABNAME, 1, 20) AS TABNAME,
  
3         COMPRESSION, ROWCOMPMODE
  
4  FROM SYSCAT.TABLES
  
5  WHERE TABSCHEMA ='TPCH';

TABSCHEMA  TABNAME              COMPRESSION ROWCOMPMODE
---------- -------------------- ----------- -----------
TPCH       CUSTOMER             N
TPCH       CUSTOMER2            R           S
TPCH       CUSTOMER3            V

  用下面的ALTER TABLE DEACTIVATE VALUE COMPRESSION语句将CUSTOMER3恢复未压缩状态,其空间占用也恢复到与压缩前大小相同。

SQL> ALTER TABLE tpch.customer3 DEACTIVATE VALUE COMPRESSION;

DB250000I: 成功地完成该命令。

耗用时间为:
32 毫秒
SQL
> reorg table tpch.customer3 resetdictionary;
DB250000I: 成功地完成该命令。
SQL
> RUNSTATS ON TABLE tpch.customer3 WITH DISTRIBUTION AND INDEXES ALL;
DB250000I: 成功地完成该命令。
SQL
> select npages*32 , cast(tabname as varchar(20)) from syscat.tables where TABSCHEMA='TPCH';

                  
1 2
-------------------- --------------------
              
262304 CUSTOMER
              
145920 CUSTOMER2
              
262016 CUSTOMER3

SQL
> SELECT SUBSTR(TABSCHEMA, 1, 10) AS TABSCHEMA,
  
2         SUBSTR(TABNAME, 1, 20) AS TABNAME,
  
3         COMPRESSION, ROWCOMPMODE
  
4  FROM SYSCAT.TABLES
  
5  WHERE TABSCHEMA ='TPCH';

TABSCHEMA  TABNAME              COMPRESSION ROWCOMPMODE
---------- -------------------- ----------- -----------
TPCH       CUSTOMER             N
TPCH       CUSTOMER2            R           S
TPCH       CUSTOMER3            N

SQL
>

  综上,db2 10.1引入的自适应压缩对于静态表的节省空间效果非常明显,对ingest导入数据的性能也有大幅度提高,而且没有影响压缩比。至于它的查询性能,留到后面的TPCH测试环节再进行测试。

${PageNumber}

  三、TPCH测试

  和前几次测试一样,主要测试数据加载和查询性能,也对压缩后的数据进行测试。

  1.准备工作

  构造测试环境,首先建立一个名为tpch的模式,并设置它为当前模式。然后执行创建表的脚本。注意tpch原始脚本包含多行,需要在db2命令行中设置-t选项,表示默认以分号而不是回车作为一个SQL语句结束的分隔符。

  Windows操作系统下不能指定数据库创建路径:

db2 => create database tpch on 'C:' dbpath on 'C:\TESTDB\db2\' USING CODESET UTF-8 TERRITORY CN pagesize 32768
SQL1052N  数据库路径
"C:\TESTDB\db2\" 不存在。
db2 => create database tpch on 'C:\TESTDB\db2\' USING CODESET UTF-8 TERRITORY CN pagesize 32768
SQL1052N  数据库路径
"C:\TESTDB\db2\" 不存在。

  在默认安装目录创建数据库:

db2 => create database tpch USING CODESET UTF-8 TERRITORY CN pagesize 32768
DB20000I  CREATE DATABASE 命令成功完成。
db2
=> connect to tpch

   数据库连接信息

数据库服务器        
= DB2/NT64 10.1.0
SQL 授权标识        
= DB2ADMIN
本地数据库别名      
= TPCH

  创建tpch模式并把它设置为默认模式:

db2 => CREATE SCHEMA tpch
DB20000I  SQL 命令成功完成。
db2
=> set current schema tpch
DB20000I  SQL 命令成功完成。
db2
=> quit
DB20000I  QUIT 命令成功完成。

  执行创建表的ddl脚本:

C:\Program Files\IBM\SQLLIB\BIN>db2 -tvf C:\Users\db2admin\Downloads\dss.ddl
CREATE TABLE NATION  
( N_NATIONKEY  INTEGER NOT NULL, N_NAME       CHAR(25) NOT NULL, N_REGIONKEY  INTEGER NOT NULL, N_COMMENT    VARCHAR(152))
DB20000I  SQL 命令成功完成。



CREATE TABLE LINEITEM
( L_ORDERKEY    INTEGER NOT NULL, L_PARTKEY     INTEGER NOT NULL, L_SUPPKEY     INTEGER NOT NULL,L_LINENUMBER  INTEGER NOT NULL, L_QUANTITY    DECIMAL(15,2) NOT NULL, L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL, L_DISCOUNT    DECIMAL(15,2) NOT NULL, L_TAX         DECIMAL(15,2) NOT NULL, L_RETURNFLAG  CHAR(1) NOT NULL, L_LINESTATUS  CHAR(1) NOT NULL, L_SHIPDATE    DATE NOT NULL, L_COMMITDATE  DATE NOT NULL, L_RECEIPTDATE DATE NOT NULL, L_SHIPINSTRUCT CHAR(25) NOT NULL, L_SHIPMODE     CHAR(10) NOT NULL, L_COMMENT      VARCHAR(44) NOT NULL)
DB20000I  SQL 命令成功完成。

  2.数据加载

  DB2的文本数据文件导入有2种方式,第一种import命令导入,第二种是load命令装入,根据上次评测的经验,选用较快的load方式,并通过load命令提供的modified by coldel选项指定分隔符。Ingest工具的性能比load要差,因此不用它来加载。

  为了对装载过程简便地进行计时,采用Windows命令行的time命令,并创建一个cr文件,用于自动输入回车符,从而输出当前时间。

C:\Program Files\IBM\SQLLIB\BIN>copy con cr

^Z
已复制        
1 个文件。

  由于Windows操作系统下不支持在一个命令行中输入多个带重定向的命令,如:time。

  因此创建一个批处理文件,把各个命令分行列在其中:

C:\Program Files\IBM\SQLLIB\BIN>notepad a.bat

  首先用一个表part来测试,装载出现问题。

C:\Program Files\IBM\SQLLIB\BIN>a

当前时间:
19:25:44.38

C:
\Program Files\IBM\SQLLIB\BIN>db2 load from  C:\Users\Administrator\Downloads\part.tbl of del MODIFIED BY COLDELX7C MESSAGES load_part.log insert into tpch.part

SQL3107W  在 LOAD 处理期间至少遇到一条警告消息。

当前时间:
19:25:46.41

  查看装载的日志文件,发现无法访问文件:

C:\Program Files\IBM\SQLLIB\BIN>dir load_part.log
驱动器 C 中的卷没有标签。
卷的序列号是 3CE2-73F3

C:
\Program Files\IBM\SQLLIB\BIN 的目录

2012/07/11  19:25               548 load_part.log
              
1 个文件            548 字节
              
0 个目录 487,517,462,528 可用字节

C:
\Program Files\IBM\SQLLIB\BIN>type load_part.log
SQL3501W  由于禁用数据库正向恢复,因此表所驻留的表空间将不被置于备份暂挂状态。

SQL3039W  可供 DATA BUFFER 的 LOAD 使用的内存禁止完全 LOAD
并行性。将使用装入并行性
"2"

SQL3109N  实用程序正在开始从文件
"C:\Users\Administrator\Downloads\part.tbl"
装入数据。

SQL2036N  文件、命名管道或设备
"C:\Users\Administrator\Downloads\part.tbl"
的路径无效。

SQL3107W  在 LOAD 处理期间至少遇到一条警告消息。

  用dir命令也无法访问磁盘上的文件,确认是用户访问权限问题:

C:\Program Files\IBM\SQLLIB\BIN>dir C:\Users\Administrator\Downloads\*tbl
拒绝访问。

  将tbl数据文件复制到当前用户目录,再运行批处理文件:

C:\Program Files\IBM\SQLLIB\BIN>a

当前时间:
19:33:19.07

C:
\Program Files\IBM\SQLLIB\BIN>db2 load from  C:\Users\db2admin\part.tbl of del MODIFIED BY COL
DELX7C MESSAGES load_part
.log insert into tpch.part

落实行数        
= 2000000

当前时间:
19:33:36.14

  测试通过,part表用时17.07秒。继续把其余7个表的load命令输入a.bat文件,执行装载命令:

C:\Program Files\IBM\SQLLIB\BIN>a

当前时间:
19:38:26.32

C:
\Program Files\IBM\SQLLIB\BIN>db2 load from  C:\Users\db2admin\partsupp.tbl of del MODIFIED BY COLDELX7C MESSAGES load_partsupp.log insert into tpch.partsupp

落实行数        
= 8000000
当前时间:
19:39:20.56

C:
\Program Files\IBM\SQLLIB\BIN>db2 load from  C:\Users\db2admin\lineitem.tbl of del MODIFIED BY COLDELX7C MESSAGES load_lineitem.log insert into tpch.lineitem

落实行数        
= 59986052
当前时间:
19:44:43.48

C:
\Program Files\IBM\SQLLIB\BIN>db2 load from  C:\Users\db2admin\orders.tbl of del MODIFIED BY COLDELX7C MESSAGES load_orders.log insert into tpch.orders

落实行数        
= 15000000
当前时间:
19:45:52.10

C:
\Program Files\IBM\SQLLIB\BIN>db2 load from  C:\Users\db2admin\customer.tbl of del MODIFIED BY COLDELX7C MESSAGES load_customer.log insert into tpch.customer

落实行数        
= 1500000
当前时间:
19:46:03.93

  测算得出,其它7个表装载的时间分别是54.2秒、5分22.9秒、1分8.6秒、11.8秒、2.4秒、1.9秒、1.8秒,加上第一个表的17.07秒,总时间8分钟。每分钟装载的数据约1.3GB,速度一般。

  如果因为某种原因,load中断,在下次重新load时需要首先用terminate参数终止上次不成功的操作,然后才能重新装载或作其他操作,否则系统提示错误,拒绝执行操作。

  如果在执行装入过程中发现操作有误、强行中止装载命令:

当前时间: 20:09:12.47

C:
\Program Files\IBM\SQLLIB\BIN>db2 load from  C:\Users\db2admin\ orders.tbl of del MODIFIED BY C
OLDELX7C MESSAGES load_orders
.log insert into tpch.orders
SQL3005N  处理被中断。
终止批处理操作吗
(Y/N)? ^C

  对应表被挂起、无法进行其他操作:

db2 => select count(*) from orders

1
-----------
SQL0668N  不允许对表
"TPCH.ORDERS" 执行操作,原因码为 "3"。  SQLSTATE=57016

  执行带TERMINATE参数的load命令结束装载,使表恢复可用状态:

C:\Program Files\IBM\SQLLIB\BIN>db2 load from  C:\Users\db2admin\ orders.tbl of del MODIFIED BY COLDELX7C MESSAGES load_orders.log TERMINATE  into tpch.orders

  记录数还是装载前的状态:

C:\Program Files\IBM\SQLLIB\BIN>db2 select count(*) from orders

1
-----------
  
15000000

  3.测试数据和查询语句的产生步骤

  主要步骤参照本系列第一篇文章《SQL Server 2012评测》。然后再针对db2的特性作修改。

  Db2对SQL语句的特殊要求主要有2点:

  (1)取前若干行的语法。db2的select语句语法不支持TOP N子句,需要修改为分析函数row_number()或用fetch first n rows only子句,其中n是整数。

  (2)日期间隔的表达式。不支持interval 'n' year/month等写法,要改为 n year/month。

${PageNumber}

  4.数据查询

  与9.7版的测试相同,为了比较不同条件下的查询结果,我们进行了4种组合的查询。分别是:单进程不压缩,并行不压缩,单进程压缩,并行压缩,每种测试做2遍,取较快的一遍的结果。

  测试工具仍选用测试9.7版时使用的db2batch。

  在修改完成的包含22个查询语句的sql脚本前端和每个查询前面加上如下参数,就可以方便地进行多次测试。

--#SET PERF_DETAIL 1 TIMESTAMP
--
#COMMENT Q1

  根据以往的经验,为了获得较好的执行计划,需要为各表创建主键和外键、并收集统计信息。然后用db2batch命令执行查询语句并计时,在Windows下用find命令查看日志获取各查询的时间。

  在创建主键和外键的脚本中插入查询当前时间命令:

C:\Program Files\IBM\SQLLIB\BIN>notepad dss.ri

  运行创建主键和外键的脚本:

C:\Program Files\IBM\SQLLIB\BIN>db2 -tvf dss.ri
select CURRENT TIMEstamp from sysibm.sysdummy1

1
--------------------------
2012-07-11-20.47.00.765000

ALTER TABLE REGION ADD PRIMARY KEY
(R_REGIONKEY)
DB20000I  SQL 命令成功完成。

select CURRENT TIMEstamp from sysibm.sysdummy1

1
--------------------------
2012-07-11-20.47.01.233000


ALTER TABLE LINEITEM ADD CONSTRAINT LINEITEM_FK1 FOREIGN KEY
(L_ORDERKEY)  references ORDERS
DB20000I  SQL 命令成功完成。

select CURRENT TIMEstamp from sysibm.sysdummy1

1
--------------------------
2012-07-11-20.55.59.278000

ALTER TABLE LINEITEM ADD CONSTRAINT LINEITEM_FK2 FOREIGN KEY
(L_PARTKEY,L_SUPPKEY) references PARTSUPP
DB20000I  SQL 命令成功完成。

  把RUNSTATS命令输入批处理文件,执行统计分析并计时:

C:\Program Files\IBM\SQLLIB\BIN>stat

当前时间:  
7:26:51.79

C:
\Program Files\IBM\SQLLIB\BIN>db2 "RUNSTATS ON TABLE tpch.part"
DB20000I  RUNSTATS 命令成功完成。

当前时间:  
7:26:54.88



C:
\Program Files\IBM\SQLLIB\BIN>db2 "RUNSTATS ON TABLE tpch.supplier"
DB20000I  RUNSTATS 命令成功完成。

当前时间:  
7:29:14.00

  把db2batch命令的查询输出重定向到日志文件:

C:\Program Files\IBM\SQLLIB\BIN>db2batch -d tpch -f tpch_db2.txt > tpch_db2_after_stat.log

  使用Windows的find命令获得每个查询的执行时间:

C:\Program Files\IBM\SQLLIB\BIN>find "耗用时间是" tpch_db2_after_stat.log
---------- C:
\PROGRAM FILES\IBM\SQLLIB\BIN\TPCH_DB2_AFTER_STAT.LOG
* 耗用时间是:    
83.711817
* 耗用时间是:    
21.806546
* 耗用时间是:    
197.635545
* 耗用时间是:    
220.533425
* 耗用时间是:    
252.570283
* 耗用时间是:    
112.265110
* 耗用时间是:    
143.012616
* 耗用时间是:    
148.730301
* 耗用时间是:    
192.328260
* 耗用时间是:    
141.922114
* 耗用时间是:    
18.140037
* 耗用时间是:    
141.315907
* 耗用时间是:    
26.713390
* 耗用时间是:    
120.015532
* 耗用时间是:    
115.234103
* 耗用时间是:    
40.183856
* 耗用时间是:    
119.457345
* 耗用时间是:    
140.056349
* 耗用时间是:    
119.394957
* 耗用时间是:  
2899.539803
* 耗用时间是:    
370.242241
* 耗用时间是:    
33.613318

  4.1压缩数据

  对表进行压缩有2种方法,一种是在创建表的时候指定压缩属性,再加载数据,另一种是对已经包含数据的非压缩表进行修改压缩属性的操作,然后重整表。前面测试结果表明,这两种方法压缩效果没有区别。由于前面测试步骤中已有数据,所以本次测试用第2种方法。

  首先用alter table ..compress yes命令改变各表的压缩属性。

C:\Program Files\IBM\SQLLIB\BIN>db2 "alter table tpch.part compress yes"
DB20000I  SQL 命令成功完成。

  再将reorg table命令和time <cr写入一个批处理文件reorg.bat并执行,重整8个文件用时大约14分钟。

C:\Program Files\IBM\SQLLIB\BIN>reorg

当前时间:  
6:46:52.07

C:
\Program Files\IBM\SQLLIB\BIN>db2 "reorg table tpch.part resetdictionary"

当前时间:  
6:47:09.33

...

C:
\Program Files\IBM\SQLLIB\BIN>db2 "reorg table tpch.supplier resetdictionary"

当前时间:  
7:00:47.88

  重整完毕后再次收集统计信息:

  C:\Program Files\IBM\SQLLIB\BIN>stat_wi

  压缩前字节数:

C:\Program Files\IBM\SQLLIB\BIN>db2 "select npages*32 , cast(tabname as varchar(20)) from syscat.tables where TABSCHEMA='TPCH'"

1                    2
-------------------- --------------------
              
262304 CUSTOMER
            
8073408 LINEITEM
                  
32 REGION
              
15808 SUPPLIER
                  
32 NATION
            
1724000 ORDERS
              
294208 PART
            
1234144 PARTSUPP

  压缩后字节数:

C:\Program Files\IBM\SQLLIB\BIN>db2 "select npages*32 , cast(tabname as varchar(20)) from syscat.tables where TABSCHEMA='TPCH'"

1                    2
-------------------- --------------------
              
144128 CUSTOMER
            
3334240 LINEITEM
                  
32 REGION
                
8704 SUPPLIER
                  
32 NATION
              
729408 ORDERS
              
101248 PART
              
440320 PARTSUPP

  从上面表的占用空间可见,对于TPC-H数据,db2 10.1版平均压缩为原来的1/3,和9.7版的压缩率差别不大。

${PageNumber}

   4.2并行查询测试

  接下来测试并行查询,则采用下面的设置。查询优化器自动采用并行查询。

C:\Program Files\IBM\SQLLIB\BIN>db2 UPDATE DBM CFG USING INTRA_PARALLEL YES
DB20000I  UPDATE DATABASE MANAGER CONFIGURATION 命令成功完成。

C:
\Program Files\IBM\SQLLIB\BIN>db2 UPDATE DBM CFG USING MAX_QUERYDEGREE 32
DB20000I  UPDATE DATABASE MANAGER CONFIGURATION 命令成功完成。

C:
\Program Files\IBM\SQLLIB\BIN>db2 get dbm cfg|find "PARALLEL"
启用分区内并行性                      
(INTRA_PARALLEL) = YES

C:
\Program Files\IBM\SQLLIB\BIN>db2 get dbm cfg|find "DEGREE"
最大查询并行度                        
(MAX_QUERYDEGREE) = 32

C:
\Program Files\IBM\SQLLIB\BIN>db2 get db cfg|find "DEGREE"
并行度                                    
(DFT_DEGREE) = 1

C:
\Program Files\IBM\SQLLIB\BIN>db2 update db cfg using DFT_DEGREE 4
DB20000I  UPDATE DATABASE CONFIGURATION 命令成功完成。

C:
\Program Files\IBM\SQLLIB\BIN>db2 get db cfg|find "DEGREE"
并行度                                    
(DFT_DEGREE) = 4

  --必须重启数据库,才能使新配置生效:

C:\Program Files\IBM\SQLLIB\BIN>db2stop force
2012-07-18 20:09:13     0   0   SQL1064N  DB2STOP 处理成功。
SQL1064N  DB2STOP 处理成功。

C:
\Program Files\IBM\SQLLIB\BIN>db2start
2012-07-18 20:09:27     0   0   SQL1063N  DB2START 处理成功。
SQL1063N  DB2START 处理成功。

  --重启数据库后,查看执行计划可以见到采用了分区内并行,并行度为4。

C:\Program Files\IBM\SQLLIB\BIN>db2expln -d tpch -q "select count(*) from tpch.nation,tpch.region" -t

******************** DYNAMIC ***************************************

==================== STATEMENT ==========================================

        Isolation Level          
= Cursor Stability
        Blocking                
= Block Unambiguous Cursors
        Query Optimization Class
= 5

        Partition Parallel      
= No
        Intra-Partition Parallel
= Yes (Bind Degree = 4    )

        SQL
Path                 = "SYSIBM", "SYSFUN", "SYSPROC", "SYSIBMADM",
                                  
"DB2ADMIN"

Statement:

  
select count(*)
  from tpch
.nation, tpch.region

Intra-Partition Parallelism Degree
= 4

  创建主键、外键用时大约9分钟,与装载数据用时差不多,统计分析用时2分23秒,这是合理的,因为前者涉及对全部数据的操作和大量数据读写、后者只是读取部分数据并记录少量的信息。

  下面是各组查询测试结果。(第20个查询在并行查询中无法在可接受的时间内返回结果,测试数据略)

 

编号
不压缩单进程
(1)
不压缩并行
(2)
不压缩并行/单进程
(2)/(1)
压缩单进程(3)
压缩并行
(4)
压缩并行/单进程
(4)/(3)
并行压缩/不压缩
(4)/(2)
单进程压缩/不压缩
(3)/(1)
01
 83.71
 67.85
0.81
 69.06
 28.94
0.42
0.43
0.82
02
 21.80
 26.27
1.21
   7.74
   4.65
0.60
0.18
0.36
03
 197.63
 98.71
0.50
 77.80
 40.90
0.53
0.41
0.39
04
 220.53
 83.45
0.38
 74.18
 44.54
0.60
0.53
0.34
05
 252.57
 83.86
0.33
 93.24
 42.04
0.45
0.50
0.37
06
 112.26
 66.66
0.59
 30.35
 29.04
0.96
0.44
0.27
07
 143.01
 82.05
0.57
 77.67
 43.60
0.56
0.53
0.54
08
 148.73
 86.22
0.58
 62.35
 36.89
0.59
0.43
0.42
09
 192.32
 122.29
0.64
 101.44
 72.60
0.72
0.59
0.53
10
 141.92
 81.95
0.58
 75.76
 40.93
0.54
0.50
0.53
11
 18.14
 10.95
0.60
   6.75
   4.18
0.62
0.38
0.37
12
 141.31
 81.22
0.57
 56.09
 36.79
0.66
0.45
0.40
13
 26.71
 17.73
0.66
 24.82
 17.90
0.72
1.01
0.93
14
 120.01
 69.66
0.58
 50.91
 29.65
0.58
0.43
0.42
15
 115.23
 67.30
0.58
 48.00
 28.66
0.60
0.43
0.42
16
 40.18
 23.30
0.58
 34.84
 19.27
0.55
0.83
0.87
17
 119.45
 69.99
0.59
 48.35
 28.21
0.58
0.40
0.40
18
 140.05
 110.91
0.79
 69.28
 60.57
0.87
0.55
0.49
19
 119.39
 69.64
0.58
 46.48
 27.08
0.58
0.39
0.39
20
2899.53
5710.49
1.97
1203.58
2338.06
1.94
0.41
0.42
21
 370.24
 216.14
0.58
 112.00
 80.95
0.72
0.37
0.30
22
 33.61
 18.22
0.54
 16.78
  8.69
0.52
0.48
0.50
不含20合计
2758.80
1554.37
0.56
1183.89
726.08
0.61
0.47
0.43
合计
5658.33
7264.86
1.28
2387.47
3064.14
1.28
0.42
0.42

  表1 TPC-H scale=10未压缩和压缩数据的测试对比,单位:秒

  与Db2 9.7版本的结果不同,10.1版本中,首先,任何一种测试组合,所有22个查询都能顺利完成,而9.7版的第20个查询在后3种情况下都无法完成;其次,无论是否压缩,并行查询的速度都比单进程都有所提高,平均提高40%,但也有个别查询性能反而下降(如第20个查询),而性能下降的查询偏偏是占总用时比重最大的,这个下降拖累了整体性能数据,造成并行比单进程用时多约30%,若不考虑第20个查询,并行不压缩用时远少于单进程不压缩用时。这个结果符合我们的预期。由于我们用来测试的机器有8个逻辑CPU,而设置默认并行度为4,在合理的范围之内,所以不会产生资源不足的副作用。再次,无论是否并行,压缩查询的速度都比不压缩都有所提高,平均提高60%,即使是耗时最长的查询也不例外。压缩是提高查询速度的有效途径,而9.7版时,压缩表的查询效果是不佳的,可能跟10.1对数据压缩的改进有关。

  由上述结果可知,一般情况下,查询的时间由长到短分别是:不压缩单进程、不压缩并行、压缩单进程、压缩并行,总之,结合压缩和并行,可能得到最好的查询性能。

  5.SQL查询语句的改写

  DB2对SQL语句书写的要求较高,这给应用开发人员带来了挑战。比如TPCH的第20个查询,下面2种逻辑上完全等价的写法,在db2 10.1执行效果却是天壤之别,运行时间差不多差了24倍。当然从测试的角度,不能随意修改查询的写法,但在查询优化器对特定写法的执行计划不佳的情况下,实际工作中人工改写是必须的。

--用时最长的第20个查询语句的原始写法
select
        s_name
,
        s_address
from
        tpch
.supplier,
        tpch
.nation
where
        s_suppkey in
(
                
select
                        ps_suppkey
                from
                        tpch
.partsupp
                where
                        ps_partkey in
(
                                
select
                                        p_partkey
                                from
                                        tpch
.part
                                where
                                        p_name like 'bisque%'
                        
)
                        and ps_availqty
> (
                                
select
                                        
0.5 * sum(l_quantity)
                                from
                                        tpch
.lineitem
                                where
                                        l_partkey
= ps_partkey
                                        and l_suppkey
= ps_suppkey
                                        and l_shipdate
>= date '1994-01-01'
                                        and l_shipdate
< date '1994-01-01' + 1 year
                        
)
        
)
        and s_nationkey
= n_nationkey
        and n_name
= 'CANADA'
order by
        s_name
fetch first
10 rows only;

  在用时最短的压缩单进程查询中也要1203秒。而同等条件下改写后的语句才50秒。

--修改后的第20个查询语句

select s_name,  s_address
from tpch
.supplier, tpch.nation
where s_suppkey in
(select ps_suppkey
from tpch
.partsupp ,(select l_partkey,l_suppkey, sum(l_quantity) l_quantity_SUM
from tpch
.lineitem,tpch.part
where l_partkey
= p_partkey and p_name like 'bisque%' and l_shipdate >= date '1994-01-01' and l_shipdate < date '1994-01-01' + 1 year GROUP BY l_partkey,l_suppkey )
where l_partkey
= ps_partkey and l_suppkey = ps_suppkey and ps_availqty > 0.5*l_quantity_SUM ) and s_nationkey = n_nationkey and n_name = 'CANADA'
order by s_name
fetch first
10 rows only;

C:
\Program Files\IBM\SQLLIB\BIN>db2batch -d tpch -f newkidq20.txt > newkidq20_after_stat_wi_comp.log

C:
\Program Files\IBM\SQLLIB\BIN>find "耗用时间是" newkidq20_after_stat_wi_comp.log

---------- NEWKIDQ20_AFTER_STAT_WI_COMP
.LOG
* 耗用时间是:    
50.200536 秒 * 总结表:

  通过分析两个查询语句的执行计划可以了解更多信息,这里不深入讨论,只是说明,db2 10.1对某些特定查询的执行计划不佳,需要人工改写SQL的写法。

  四、小结

  经过这次测试, 我们对Windows版DB2 10.1数据库已经有了初步的印象,安装比较容易,功能比较强大,总体性能也比较好,能充分利用硬件资源。尤其是数据压缩、分区内并行对查询性能提高较明显,最重要的,一些语句虽然耗时较长,但都能输出结果,对比9.7版有了很大改善。再次,新推出的Ingest工具允许添加复杂的SQL语句对数据进行操作。压缩表的导入性能超过普通表。而且,Linux下的各种命令大部分不加修改地都能在Windows环境中继续使用,可以缩短学习周期。

  要说存在的问题,首先,对部分SQL书写的要求比较高,否则执行计划不良。其次, Ingest工具在默认配置下性能不如传统load工具,而且某些行为与load不一致,比如代码页问题。再就是DB2系统的复杂性,安装时系统设定的默认值往往不够用,数百个和性能相关的各种配置参数需要记忆。另外, 服务器安装包不包含图形化管理工具和文档,需要从因特网另外下载,对数据库管理不是很方便。

  Oracle兼容功能虽然有很多改进,但模仿得还是不是太完整,需要增加对connect by level的支持并改进执行计划的显示方式和显示速度。

  IBM很重视文档的本地化工作,10.1版发布不久就公布了简体中文的文档,这点很有利于技术人员熟悉他们的产品,在官方技术网站也有大量中文DB2技术文章和入门教材,这些都是很好的学习资源。

  总的来说,IBM DB2是一个功能全面,性能均衡,运行稳定的主流商用数据库,这也是在金融行业一直占据主流地位的原因所在。

0
相关文章