级别: 初级 Howard Goldberg (howard_goldberg@ml.com),
2005 年 5 月 01 日 DB2 Magazine 是一种专门针对数据库管理员、分析员、程序员、设计师、顾问以及 MIS/DP 经理的季刊,其内容涵盖了所有 DB2 平台(包括 IBM AIX、Hewlett-Packard HP-UX、Sun Solaris、SCO UnixWare、Linux、Microsoft Windows NT、Microsoft Windows 95、Microsoft Windows 98、IBM OS/2、IBM OS/400、IBM MVS、IBM OS/390、IBM VM 和 IBM VSE )的各种主题。
为了从 DB2 Information Integrator 获得最佳性能,DBA 需要知道哪些东西。
大多数 DBA 都知道,对于性能低下的 SQL 查询,为了发现、评估和实施有助于改善其性能的改进方法,需要完成哪些任务。然而对于联邦查询,DBA 必须学习新的技巧,拓宽一般情况下的查询调优任务列表,以便处理由 DB2 Information Integrator (DB2 II) 提供的新功能。
DB2 II 支持跨多种数据源的联邦查询,这些数据源包括 SQL Server、Oracle、Informix、Sybase 和 DB2 Universal Database (UDB) for z/OS,以及 iSeries、Linux、Unix 和 Window。DB2 II 产品是一个中间件,其中包含的优化和数据访问技术,充分调动了底层数据源的能力,并为这些不同的源提供一种统一访问语言(SQL)。
DB2 II 产品已经为那些之前不能访问或者不易访问的信息源敞开了大门。尽管如此,随着每一项新的数据支持技术的出现,新的调优机会也应运而生。使用 DB2 II 并不确保最优执行每一个查询。DBA 要做的工作,仍然是发现和调优性能低下的查询。
联邦对象带来了新的挑战。在这一期,我将解释调优联邦查询时所需的任务和工具。本文假设您对 DB2 II 有一个基本的了解。您可以通过在参考资料小节中列出的文章,或者通过 ibm.com/software/data/integration 温习 DB2 II 方面的知识。如果您想了解 Merrill Lynch(我的雇主),是如何利用 DB2 II 解决现实生活中的业务问题的,请参阅文章 "Taming the Beast"。
基本调优任务
对任何性能低下的 SQL 语句进行调优都需要一种有条不紊的方法。毫无计划地更改参数只能让每一次做出的更改难于判断效果。如果某一次更改对性能起了反作用,那么您需要知道应该退回到哪一次更改。
不管调优什么 SQL,都应该执行以下任务:
- 评估当前性能,并记录到文档。
- 与创建查询的人会谈,并得出合理的性能预期。
- 建立查询的业务目标。
- 对于来自生产系统的查询,获得一个 Explain 计划。
- 如果可行的话,在测试系统上重建环境,并重新运行查询。
- 对于与查询相关的所有表,确信最近在这些表上执行了 Runstats 或与之等价的远程命令。
- 确保各个表的重组,以匹配它们的集群索引。
- 查找 WHERE 子句中索引列上的 SQL 函数,这些函数可能导致优化器忽略了索引。
- 确保在 WHERE 子句中尽可能使用索引列。
- 查找笛卡儿积(Cartesian products)。
- 跟踪每一项更改的效果,每次跟踪一项。
联邦调优任务
由于联邦查询连接到了不同的数据源,调优的第一步是将查询分解为两部分:本地和远程。本地部分使用驻留在 DB2 II 服务器上的对象,而远程部分使用驻留在远程主机上的对象。通过这种方式划分联邦查询,有助于判断影响性能问题的根源。
DB2 II 服务器中的所有联邦对象在 syscat.tables 编目表中都是以昵称(TYPE=N)的形式标识的。也可以通过 EXPLAIN 命令识别查询中的联邦对象,该命令将显示 DB2 II 引擎选择的全局访问计划。EXPLAIN 命令的输出是判断优化器是否将为查询使用“叠加(push-down)”处理(即在远程服务器上执行的处理)的惟一途径。DB2 II 使用来自包装器、服务器和昵称对象的信息,来判断什么任务可以叠加到远程服务器。
清单 1 展示了一个存储在 db2ii-query.sql 文件中的联邦查询的实例。以粗体标记的表(mids.tbacct 和 mids.tbacct -hldr)上的查询引用了远程对象。而表 table hjg.iitbl 则是在 DB2 II 服务器本地。Explain 将把这个查询分解成几个部分。对于将要使用叠加处理的部分,以 ship 这个词标记。清单 2 展示了 Explain 输出的一个缩节本。优化器将子查询 #1 标记为“shipable”。
清单 1. 联邦 SQL 查询
db2expln -d dbdsdr -stmtfile db2ii-query.sql -o db2ii-query.out -terminator ";" -g
select a.dsssca-no
, a.dssas-ty-cd
, imlp-1st-nm
, imlp-lst-nm
, mlp-st-cd
ac-eom-ast-am
from mids.tbacct a
, mids.tbacct-hldr ah
,hjg.iitbl
where a.dsssca-no =ah.dsssca-no
and ac-eom-ast-am > 1000000
and st-cd =mlp-st-cd and-mlp-st cd ='ny'
fetch first 1 rows only
|
清单 2. Explain 输出,其中标记了要做叠加处理的查询
| Ship Distributed Subquery #1
| | #Columns = 6
Return Data to Application
| #Columns = 6
|
查询的这个部分由优化器生成,其中只包含那些访问远程数据源的对象。清单 3 展示了 Explain 输出的一部分,其中有重写后的查询。这个清单中的输出含有关于查询的信息,包括将被发送到远程数据源的 SQL、使用的昵称以及远程服务器的名称及相关版本(在这里是 MIDASP)。如果您对完整的 Explain 输出有兴趣的话,请下载文件: IBM DB2 Universal Database SQL Explain Tool (DOC, 30K)。
清单 3. 优化器重写的访问远程对象的查询。Distributed Substatement #1:
Server: MIDASP (DB2/UDB 7.1)
SQL Statement:
SELECT A0."DSSSCA-NO", A0."AC-EOM-AST-AM", A0."DSSAS-TY-CD", A1."MLP-ST- CD", A1."IMLP-1ST-NM", A1."IMLP-LST-NM"
FROM "MIDS"."TBACCT" A0, "MIDS"."TBACCT-HLDR" A1
WHERE (1000000 < A0."AC-EOM-AST-AM") AND (A1."MLP-ST-CD" ='NY') AND (A0."DSSSCA-NO" =A1."DSSSCA-NO") FOR READ ONLY
Nicknames Referenced:
MIDS.TBACCT-HLDR ID = 33125
Base = MIDS.TBACCT-HLDR
MIDS.TBACCT ID = 33124
Base = MIDS.TBACCT
|
如果将两个远程表(a.dsssca-no =ah.dsssca-no)之间的连接谓词去掉,那么将得到一个笛卡儿乘积。如果在做出这样的更改之后发出 EXPLAIN 命令,则 DB2 II 优化器会把数据取到它的服务器上,并在本地执行连接操作,而不是把连接发送到远程服务器,这样可以减少网络传输。清单 4 展示了这个 SQL 例子,并给出了与之相关的 Explain 输出的一部分(完整的输出在网上有提供)。
清单 4. 重写的查询,将数据取到 DB2 II 服务器进行本地处理
| Ship Distributed Subquery #1
| | #Columns = 3
| Nested Loop Join
| | Access Table Name = HJG.IITBL ID = 62,24
| | | #Columns = 1
| | | Relation Scan
| | | | Prefetch: Eligible
| | | Lock Intents
| | | | Table: Intent Share
| | | | Row : Next Key Share
| | | Sargable Predicate(s)
| | | | #Predicates = 1
| | | | Process Probe Table for Hash Join
Return Data to Application
| #Columns = 6
Distributed Substatement #1:
Server: MIDASP (DB2/UDB 7.1)
SQL Statement:
SELECT A0."AC_EOM_AST_AM", A0."DSSSCA_NO",
A0."DSSAS_TY_CD"
FROM "MIDS"."TBACCT" A0
WHERE (1000000 < A0."AC_EOM_AST_AM")
FOR READ ONLY
Nicknames Referenced:
MIDS.TBACCT ID = 33124
Base = MIDS.TBACCT
#Output Columns = 3
Distributed Substatement #2:
Server: MIDASP (DB2/UDB 7.1)
SQL Statement:
SELECT A0."MLP_ST_CD", A0."IMLP_1ST_NM",
A0."IMLP_LST_NM"
FROM "MIDS"."TBACCT_HLDR" A0
WHERE (A0."MLP_ST_CD" ='NY')
FOR READ ONLY
Nicknames Referenced:
MIDS.TBACCT_HLDR ID = 33125
Base = MIDS.TBACCT_HLDR
#Output Columns = 3
End of section
|
在 Explain 命令中使用 -g 选项可以增加访问计划的树状图形显示,类似于 DB2 Control Center 的 visual Explain (见清单 5)。
叠加处理
在用 EXPLAIN 命令分析了访问计划,并且识别了本地和远程对象之后,真正的工作就开始了。您必须确定是查询的哪一部分导致了性能瓶颈。
如果看到查询的一个部分引用了远程对象,但处理没有被发送到远程数据源,那么您可能已经发现了问题的起因。但是,没有明确的规则可以一针见血地指出问题所在。很多调优都需要反复试验。如果您怀疑查询的某个部分应该被叠加,但是 Explain 显示并没有发生该叠加,那么接下来要做的就是,检查那些对优化器的访问路径决策有影响的参数。
虽然 DB2 II 引擎努力地送出尽可能多的工作,以便优化性能,但是,如果由于函数方面的问题而没有送出工作,或者如果优化器断定本地处理更为高效,那么 DB2 II 引擎就会在本地处理工作。
查询中可能阻碍叠加处理发生的函数方面的问题包括:
- 对于某个函数,DB2 II 知道在远程没有与之对等的函数。
- 某个 SQL 结构在远程数据源上不受支持,因而不能重写成遵从远程数据源的 SQL 本地语言的形式。
- 远程数据源上的一个排序序列不同于 DB2 II(或另一个远程数据源)上的排序序列,这将导致一些 SORT 和不等价的谓词不能应用到基于字符的属性上。
记住,DB2 II 还可能因为性能方面的原因而避免使用叠加,例如避免笛卡儿乘积。笛卡儿乘积会生成很多行,因而将导致过多的网络传输。为了避免这种情况,优化器可以决定把连接所涉及的表中的数据取放到 DB2 II 服务器中,并在本地执行连接。
昵称统计信息
DB2 II 服务器不把处理放到远程服务器上执行的最常见的一个原因是,在远程数据源上,关于对象的统计信息是过时的,或者根本不存在。当创建昵称时,远程数据源的统计信息被检索并插入到 DB2 II 本地编目中。通过对昵称进行 NNSTAT 存储过程,可以从远程数据源刷新统计信息。然而,这种方法不能保证远程统计信息是最新的。对于将要更新的统计信息,在使用 CREATE NICKNAME 或 NNSTAT 命令将刷新后的统计信息传播到 DB2 II 服务器之前,必须在远程对象的源上执行 Runstats 实用程序(或在远程数据源上与之等效的实用程序)。
为了使远程服务器信息尽可能准确,DB2 II 8.2 允许按照设定的时间间隔调度 NNSTAT 命令。将来的版本可能会自动地按设定的频率判断一个远程对象的统计信息是否已发生变化,并更新 DB2 II 编目中的统计信息。
DB2 II 服务器选项
您还可以使用另外一组参数来影响叠加处理的行为:服务器对象选项。使用表 1 中的选项将远程数据源的属性(如字符串排序序列)告知联邦服务器。
当您提供更多关于远程数据源的信息时,就是在帮助优化器理解,到远程数据源的叠加处理可能更为高效。例如,将 CPU-RATIO 选项设为 0.1 表明远程服务器的能力是本地 DB2 II 服务器十倍那么强。只要没有函数方面的问题,得到上述信息的优化器很可能会选择叠加尽可能多的处理。
另一个会影响叠加行为的参数是 db2-maximal-pushdown。优化器的缺省行为是根据最低预估成本(db2-maximal-pushdown = 'N')估计叠加的机会大小。把 db2-maximal-pushdown 参数设为 'Y' 将改变优化器的估计标准,而更加重视网络传输量。如果是这样设置,那么该选项将导致优化器偏好本地 DB2 II 服务器与远程数据源之间网络通信量较少的策略。您可以使用这个选项,通过改变优化器决策矩阵中的一个核心参数,来比较查询的性能。
您还可以用不同的选项设置创建到相同数据源的多个服务器对象。在调优实践中使用这个功能来判断不同选项设置的效用。您可以使用 SET SERVER 命令临时设置服务器选项,后面我还会更详细地解释。
昵称参数
您可以修改与某个昵称相关的一列,方法是改变其本地类型映射,或者添加一个列选项。不管采用哪种方法,这种附加信息都将促使优化器使用叠加处理。
例如,Oracle 使用 (38,0) 数据类型表示一个整数,但 DB2 II 服务器会将该数据类型翻译成一个浮点数据类型。通常,对于一个查询,需要连接分别来自这两种数据库的表,在结果集返回之前,DB2 II 服务器会定位到所有数据来进行列的比较。如果将昵称列的数据类型修改成整型,那么优化器会决定在远程数据源上执行工作。修改昵称的命令语法是:
alter nickname ben.
timesheets-short alter
column hours local type
integer
|
将一个列选项应用于某个昵称列,还可能影响优化器对叠加方法的使用。例如,如果指示优化器,有一个列具有以字符表示的数字,则会导致优化器将排序处理叠加到远程数据源上执行,即使排序序列不相同也在所不惜。表 2 展示了会影响优化器选择的列选项。下面的语法展示了如何设置昵称列上的列选项:
alter nickname ben.
timesheets alter column
employee-number
options (set numeric string
'y' )
|
有用的工具
您可以使用很多工具来帮助调优联邦查询。我已经提到了 Explain 实用程序,这是最重要的一个。记录查询的执行度量是一种基本的调优任务,其他工具在这方面可以起到辅助作用。
例如,通过使用 db2 命令的 -l 选项,可以创建一个日志文件,文件中包含查询的开始时间和结束时间。
db2 -l < log file name > -tvf
< file containing SQL >
|
您还可以使用 db2batch 实用程序记录查询计时。这个标准实用程序是 DB2 附带的,用于基准化查询。该工具最简单的用法是这样的:
db2batch -d < database name > -f
< file containing SQL >
|
另一个用于监控联邦查询的执行情况,以及监控资源利用情况的得力工具是 DB2 snapshot。snapshot 显示消耗的时间和有关联邦查询的其他关键信息,以及联邦查询的所有远程分段。表 3 展示了启动 snapshot 命令的两种方法。
在为 Linux、Unix 和 Windows version 8 等环境设计的 DB2 UDB 版本中,IBM 创建了很多基于 snapshot API 的用户定义函数。这些 UDF 使用 SQL 语法来调用,它们分行和列返回 snapshot 的值。我推荐使用的这些新函数为您提供了获得调优的关键性能的标准方式。这些技术可以在同类软件间共享,并且是可移植的。将 snapshot 函数输出与数据库编目信息相连接的这种能力优化和增强了收集过程,并加快了解决问题的速度。一些非常复杂的公式可以封装在 SQL 语句或存储过程中。(要了解关于 snapshots 的更多信息,请参阅参考资料中的文章)。
您可以使用 CREATE SERVER 命令永久地设置 DB2 II 对象的选项。为了临时设置这些选项,可以使用 SET SERVER 选项命令。该命令的语法如下:
set server cpu-ratio to 0.1
for server ben
|
在以上的 SET SERVER 例子中,CPU-RATIO 被设为 0.1,但只在当前会话的生命周期内有效。在调优查询的时候请使用这个命令,因为它使您可以重复测试不同的情况,并使用 Explain 实用程序检查结果。与创建多个带不同选项的服务器,或者通过删除已有的服务器对象来更改设置这些做法相比,这种方法干扰更少,并且也灵活得多。
为了确定联邦查询某一部分的各项性能,或者判断是否正确地设置了访问许可,可以使用 set passthru 命令。该命令使用户可以直接访问远程数据源,而不是借助联邦引擎。一旦设置了 passthru,用户就可以用合法的 ID 和密码登录到远程数据源上。有一点要小心:如果您希望下次还使用联邦引擎,那么应记得执行 SET SERVER RESET 命令将此选项关闭。还应注意的是,passthru 模式下的查询执行和使用本地客户机接口不同。DB2 II 增加了一些系统开销。
DBA 发挥作用
DB2 II 的精彩之处在于,它隐藏了执行跨平台连接和更新的复杂性。DB2 II 使开发人员不必编写重复、复杂且繁琐的例程,因而可以将注意力放在解决业务问题和加快推向市场上来。IBM 正在努力使这个软件更具自主性。但仍需要有人来对查询进行调优,以便提高其性能。在这方面,DBA 还有很多工作要做。
参考资料
关于作者  | |  | Howard Goldberg 有超过 22 年的 IT 工作经验,主要是在数据库和数据仓库领域。他同大型主机和分布式平台上的 DB2 都打过交道,并且曾经在很多项目的整个生命周期中一直担任领导工作。Goldberg 是 Merrill Lynch 的副总裁,这是一家顶尖的金融公司,也是 IBM Information Integration Leadership Board 的成员之一。 |
对本文的评价
|