IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Information Management | WebSphere  >

使用 IBM WebSphere Information Integrator 中的数据联邦技术: 第 2 部分:数据联邦使用示例与性能调优

介绍数据联邦系列的第 2 部分

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 中级

Anjali Betawadkar-Norwood (anorwood@us.ibm.com), 顾问软件工程师, IBM Silicon Valley Lab
Eileen Lin (etlin@us.ibm.com), 高级技术员工, IBM Silicon Valley Lab
Ioana Ursu (ursu@us.ibm.com), 高级软件工程师, IBM Silicon Valley Lab

2005 年 7 月 07 日

数据联邦为集成企业内各种不同的数据提供了一种途径。本文是一个由两部分组成的系列中的第二篇文章,文中将讨论联邦查询优化,演示一些使用示例,并讨论 WebSphere® Information Integrator 在性能调优方面的考虑。

简介

第 1 部分: 设计和配置 讨论了对集成来自不同数据源的信息的需求。文中描述了一个理想的信息管理系统应具备的特征,并详细介绍了如何使用 WebSphere Information Integrator 中的数据联邦技术来构建那样的系统。该文以一个电子商务场景为例,讲解了建立联邦系统的必要步骤和某些方面的考虑。

第 2 部分:

  • 回顾第 1 部分中建立的电子商务场景。
  • 对联邦查询优化作一个概述。
  • 阐释如何解释联邦查询执行计划。
  • 演示可以对远程数据执行的操作和查询。
  • 提供关于如何调优联邦系统中一个分布式查询的性能的提示和技巧。

取决于对数据联邦技术的熟悉程度,在进入关于使用实例和性能调优的讨论之前,部分读者必须阅读我们之前的文章。不过,在这里对之前的文章作一个回顾,以作为背景信息,还是有所帮助的。





回页首


简短的回顾

WebSphere Information Integrator 联邦系统的核心由一个起联邦服务器作用的 DB2 实例组成。其他组件包括一个作为联邦数据库的数据库,一个或多个数据源,以及访问数据库和数据源的一些客户端(用户和应用程序)。为响应一个应用程序 SQL 语句,联邦服务器自动生成到多个数据源的分布式请求。由于联邦系统包括一个 DB2 数据库,因此还可以在其中存储本地数据以及来自本地和远程表的相关信息。

图 1 阐释了一个客户在线提交订单的电子商务场景。在后端,一个全球性仓库使用 WebSphere Information Integrator 来集成关于客户、订单、商品和供应商的本地和远程数据。这些 XML 文档格式的订单被路由到全球仓库,而客户信息是在一个名为 CUSTOMERS 的本地数据库中维护的。

通过使用 WebSphere Information Integrator 中的数据联邦技术,这个全球仓库被连接到美国和加拿大的两个地区仓库。在每个仓库中,关于商品和供应商的信息分别存储在表 ITEMS 和 SUPPLIERS 中。此外,每件商品的商品 ID 和供应商 ID 存储在表 ITEM_SUPPLIED 中。美国的仓库基于 DB2 for z/OS 和 OS/390 系统,而加拿大的仓库在一个 Oracle 系统中。另一个名为 Credit Checking 服务器的 Oracle 实例则跟踪具有不良信用历史的客户,从联邦系统可以访问到这个实例。


图 1. 客户订购场景
客户订购场景

图 2 展示了这个联邦系统的配置。三个 包装器(wrapper) 提供对四个被归类为 服务器(server) 的数据源(包括包含 Web 订单的 XML 文件)的访问。所有远程数据集都按昵称(nickname)归类。关于联邦对象的信息存储在 DB2 系统编目中,在 图 2 中也叫全局编目。


图 2. 联邦系统
联邦系统

在描述对联邦系统执行的不同类型的查询和操作之前,我们首先对分布式查询的处理过程作一个概述。





回页首


联邦查询优化

为了阅读或修改远程数据源中的数据,您提交引用了昵称的 SQL 查询给联邦 DB2 服务器。为了处理该查询,DB2 查询编译器查阅 DB2 联邦数据库系统编目中的信息以及数据源包装器模块中的信息。这包括关于建立到数据源的连接的信息、远程服务器属性、数据类型和函数映射、索引信息以及远程对象统计信息。查询编译过程中,将从语法和语义上分析输入语句。查询编译器将视图定义展开成主语句块,从而产生一个更复杂的语句。在视图展开的过程中,有时可以提供更好的优化机会。

接着,该语句要经过一个重写阶段。重写是一种优化策略,它将一个有效的查询转化成语义上相等的一种新形式,这种新的形式执行起来更为高效。对于非常复杂的查询,例如带有很多子查询或连接的查询,重写阶段尤其重要。

查询编译器主要可以执行两种类型的重写:

  • 运算合并
  • 谓词操作

运算合并的例子包括视图合并和子查询-连接(subquery-to-join)转换。在 SELECT 语句中使用视图,可以限制表的连接顺序,同时也限制查询优化器在考虑访问计划时的选择。通过合并视图,可以解除这种限制。

类似地,子查询会使连接按照一定的顺序执行,而这种顺序也许不是最优的。但是通过积极地将子查询重写成连接的形式,可以缓解这一问题。在更复杂的查询中,尤其是涉及到视图时,常常会创建出冗余的连接。重写阶段会检测这些冗余,并简化语句。另一方面,重写阶段可能会通过传递引入隐含谓词。所以,优化器在为查询选择最佳访问计划时,会考虑其他的连接枚举候选项。

在重写查询时,可以应用某些试探法。典型的例子就是“谓词下推(predicate push down)”。通过这种试探法,可以尽快(尽可能接近表访问)地在查询中应用谓词。这些规则可以显著减少查询执行时间。

联邦服务器允许使用富 SQL 方言来提交查询。与远程数据源上支持的 SQL 方言相比,这种方言可以提供更多的功能。虽然联邦服务器可以弥补数据服务器上的功能缺失,但这要求操作发生在联邦服务器上。

查询中引用关系昵称的部分要通过一个 Push Down Analysis(PDA) 组件。PDA 告诉查询优化器一个操作是否可以在某个远程数据源上执行。操作可以是一个关系运算符,或者系统或用户定义的函数,也可以是一个 SQL 操作符,例如 GROUP BYORDER BY 等。

不能下推的函数和操作会大大影响查询的性能。考虑在联邦服务器上,而不是在远程数据源上执行的选择谓词的影响。这种方法要求联邦系统首先从远程数据源获取由谓词引用的数据的一个超集,然后通过谓词在本地对其进行过滤。取决于表的大小和网络的传输情况,查询性能可能会很糟糕。

内部的服务器属性是决定联邦系统与远程数据源各自所支持的功能的不同之处的关键因素。PDA 使用这些内部服务器属性来决定一个操作是否能在远程执行。这些不同之处可分为三类:

  • SQL 语言能力
  • SQL 限制
  • 各种其他的特定于服务器的限制

下面是关于联邦服务器对缺失的远程 SQL 语言能力作出补偿的一些例子:

  1. 早期版本的 Oracle 仅支持受限制的 CASE 语句。联邦服务器将这种受限版本映射到 Oracle 中的 DECODE 函数。然而,当您使用更复杂的 CASE 语句时,查询编译器将检测到这一限制,将受支持的功能下推到 Oracle 服务器,并通过在联邦服务器执行来弥补缺失的功能。
  2. 有些数据源,例如 DB2 for z/OS 和 OS/390,不允许表达式作为 GROUP BY 子句的一部分。联邦服务器需要在本地执行该操作。
  3. 有些关系数据库管理系统(RDBMS),例如 Sybase,不支持在 FROM 子句中使用表表达式。如果编译器不能通过重写语句将这些表表达式合并成封闭的子选择(例如受某些函数的副作用的影响),那么必须在本地执行封闭的子选择语句。

举个补偿 SQL 限制的例子,考虑联邦服务器可能允许使用大于其他远程数据源所允许的长度的字符串。超过远程长度限制的字符串不能嵌入到远程语句中。PDA 决定将这些字符串以主机变量还是参数标记符的形式发送。如果两种形式都不行,那么任何使用大型字符串的表达式都需要在本地计算。类似地,数据源对于最大或最小的数值也可能有限制。如果一个表达式包含超出远程限制的值,那么就不能下推那些表达式。

最后,关于特定于服务器的限制的一个例子是,DB2 Server for VM 和 VSE 数据源不支持在主机变量和参数标记符中使用 NULL。如果远程数据源不能处理主机变量或参数标记符中的 NULL,那么任何需要绑定一个可以为空的值的函数都必须在本地计算。因此,远程表的定义允许列可以为空这一点非常重要。联邦服务器在昵称注册时获取这种信息。

非关系数据源与关系数据源的建模方式不一样。非关系数据源的特征都封装在包装器中。下推的决定是包装器在计划阶段与查询优化器一起做出的。因此,查询中的非关系部分不会经过下推分析阶段。

联邦系统中的查询优化器使用存储在 DB2 联邦数据库系统编目中的信息,加上系统配置信息和查询需求,根据成本估计来生成最佳计划。关于系统配置的信息包括缓冲池的大小、排序堆的大小等等。查询需求包括为查询启用的当前优化技术的类别以及是否应该将查询优化成在最短时间返回首行,而不是返回整个结果集,等等。联邦系统上查询优化器的输出是联邦查询执行计划(Federated Query Execution Plan,FQEP)。





回页首


解释联邦查询执行计划(FQEP)

通过 FQEP 可以洞察查询如何执行。有很多方法可以查看 FQEP,包括 Visual Explain、Explain、db2expln 等。要了解关于使用 SQL Explain 的细节,请参阅 IBM DB2 Universal Database Administration Guide: Performance (见 参考资料)。

联邦查询优化器为 FQEP 添加了两种计划操作符:

  1. 对于关系数据,从远程数据源到联邦服务器或者相反方向的数据传送发生在一个 SHIP 操作符中。联邦服务器通过数据源本地 SQL 方言中的 SQL 语句将对数据的远程请求发送到远程关系数据源。对于 SELECT 查询,远程 SQL 语句中的文本可以在查询执行计划中与 SHIP 操作符相关的细节中找到。对于使用了昵称的 INSERTUPDATEDELETE 查询,在某些情况下(后面会解释),所有工作可能都是由远程数据源来做,而在 FQEP 中没有 SHIP 操作符。在这种情况下,RETURN 操作符的细节包括被传递到远程数据源的远程 SQL 语句的文本。
  2. 对于非关系昵称,RPD (Remote PushDown) 操作符将访问逻辑封装在 FQEP 中。如果一个查询引用了非关系昵称,则查询中涉及到这个昵称的部分将不会经过下推分析阶段(而涉及关系昵称的部分会经过这个阶段)。在为查询生成计划的过程中,查询优化器与非关系包装器通信。查询优化器与包装器一道决定如何访问数据。RPD 与 SHIP 之间主要的不同在于,RPD 操作符不包含 SQL 语句。RPD 操作符中的远程访问计划是由包装器构造的,其中包含为调用来自非关系数据源的远程请求所需的规范。

FQEP 中的所有操作符都有一个称作服务器属性的额外属性。这个属性表示将在那里执行操作的服务器或数据源的名称。





回页首


模拟使用联邦系统

下面几个小节提供了关于如何使用联邦服务器来处理在线商店场景中可能出现的不同类型查询的例子。通过每个查询的 FQEP,可以洞察查询的执行。这些例子可归入到以下几个领域:

记住,下面为每个查询提供的 FQEP 演示了在 WebSphere Information Integrator 联邦系统中如何执行查询的一种可能性。要获得关于如何解释带数据分区功能的联邦系统中的查询执行计划的指南,请参阅“WebSphere Information Integrator V8.2 中的并行性”(developerWorks,2005 年 2 月,见 参考资料)。

关联远程信息

您可以将多个数据源上的信息,包括本地数据关联起来。下面是三个例子:

1. 利用关系昵称关联信息
客户关系代表想要发现被列入不良信用名单中的客户的名称和债务历史。

SELECT customer_name, customer_debt
FROM customers, bad_credit
WHERE customers.customer_id = bad_credit.customer_id;

图 3 展示了一个可能的计划:


图 3. 涉及关系昵称的连接的 FQEP
涉及关系昵称的连接的 FQEP

这是表 CUSTOMERS 与昵称 BAD_CREDIT 之间的一个散列连接(hash join),前者在联邦服务器本地,后者引用一个远程 Oracle 表。该连接的执行过程包括扫描散列连接中的内表 CUSTOMERS,并通过散列连接列的值生成一个查找表。然后,它使用 SHIP 操作符读外表 BAD_CREDIT,散列连接列的值,并检查为内表生成的查找表。

2. 利用非关系昵称关联信息
仓库管理员想要找出与某个客户相关的所有订单。下面是查询:

SELECT c.customer_name, o.order_id, o.order_date, i.item_id, i.item_quantity
FROM customers c, xml.orders o, xml.order_items i
WHERE c.customer_id='1234567890'
AND c.customer_id=o.customer_id
AND o.oid=i.oid;

在这个例子中,ORDERS 和 ORDER_ITEMS 昵称都是用 XML 包装器来访问。图 4 展示了一个在联邦服务器使用嵌套循环连接操作符来计算这个查询的计划。这里没有与每个 RPD 操作符相关的 SQL 语句,因为 ORDERS 和 ORDER_ITEMS 不是关系昵称。


图 4. 连接非关系昵称的 FQEP
连接非关系昵称的 FQEP

3. 引用标量子查询
仓库管理员想要找出在美国的仓库中有哪些商品的供应量大于加拿大仓库中所有商品的供应量。这个查询使用一个标量子查询来计算 ITEM_STOCKED 列上最大的供应量:

SELECT COUNT(*)
FROM usa.items
WHERE item_stocked > (SELECT MAX(item_stocked) FROM canada.items);

图 5 展示了带 SHIP 操作符的计划,每个 SHIP 操作符按解释编号:


图 5. 引用非分配的标量子查询的 FQEP
引用非分配的标量子查询的 FQEP

昵称 CANADA.ITEMS 和 USA.ITEMS 在两个不同的远程数据源上。首先需要将标量子查询的结果传送到联邦服务器。这个需求由 SHIP1 操作符捕捉。与 SHIP1 操作符相关的语句表明该标量子查询在 Oracle 上计算。

SELECT MAX (a0."ITEMS_STOCKED") FROM "ORAUSER1"."ITEMS" a0;

之后,通过 SHIP2 操作符将这个值从联邦服务器送到美国仓库,这个 SHIP 操作符没有相关的 SQL 语句。SHIP3 操作符包含一个语句,该语句表明标量子查询的结果放在一个主机变量中。

SELECT COUNT (*)
FROM "MVSUSER1"."ITEMS" a0
WHERE (:h0 < a0."ITEM_STOCKED");

修改远程信息

这一节提供三个关于修改远程信息的例子。通过 WebSphere Information Integrator,可以直接创建远程数据源上的表。对于关系昵称,也可以执行 INSERTUPDATEDELETE 操作,但是对于非关系昵称不可以执行这些操作。除了这里提供的 INSERT 例子外,还可以对关系昵称发出 UPDATEDELETE 语句,就像它们是本地表一样。

1. 从联邦系统上创建远程表
假设管理员需要在信用检查服务器上创建一个新表,用于存储关于被列入不良信用名单、需要进行法律诉讼的客户的信息。您可以使用 PASSTHRU 会话直接将 CREATE TABLE 语句发送到数据源,并为这个新表创建一个昵称。在 WebSphere Information Integrator 中,联邦系统提供了一种名为 Transparent DDL (Data Definition Language) 的特性,它可以使用一个语句来完成这两步,如下所示。

CREATE TABLE customers_to_sue 
 (customer_id char(10) not null,
  customer_debt decimal(31,2), 
  legal_status varchar(20))
OPTIONS (REMOTE_SERVER 'CREDIT_SERVER',
         REMOTE_SCHEMA 'crduser1');

该语句在被称作 CREDIT_SERVER 的远程数据源上创建一个远程表,同时创建一个引用这个新的远程表的昵称。

2. 插入来自相同数据源的数据
仓库的信用调查分析人员(credit officer)想要使用关于那些超支金额大于 $50,000 的客户的信息填充 CUSTOMERS_TO_SUE 昵称。这种客户信息从 BAD_CREDIT 昵称获得,这个昵称与 CUSTOMERS_TO_SUE 昵称处在同一个数据源上。

INSERT INTO customers_to_sue
SELECT customer_id, customer_debt, 'new'
FROM bad_credit WHERE customer_debt > 50,000;

图 6 展示了一个完整的下推计划。


图 6. 插入来自相同数据源的数据的 FQEP
插入来自相同数据源的数据的 FQEP

在这里,整个查询都由 Oracle 服务器执行,所以只能看到一个 RETURN 操作符,而看不到任何 SHIP 操作符。在 RETURN 操作符中可以找到被发送到 Oracle 的语句。

INSERT INTO "CRDUSER1"."CUSTOMERS_TO_SUE"
("CUSTOMER_ID", "CUSTOMER_DEBT", "LEGAL_STATUS")
SELECT a0."CUSTOMER_ID", a0."CUSTOMER_DEBT", 'new'
FROM "CRDUSER1"."BAD_CREDIT" a0
WHERE (50,000 < a0."ACCT_BAL");

3. 插入来自不同数据源的数据
仓库信用调查分析人员使用类似的查询将关于余额超过 $5,000 的客户的信息存储在昵称 BAD_CREDIT 中。在这个查询中,客户信息来自联邦服务器上的 CUSTOMERS 表。

INSERT INTO bad_credit (customer_id, customer_debt)
SELECT customer_id, customer_balance
FROM customers 
WHERE customer_balance > 5000;

图 7 展示了执行计划。


图 7. 插入来自不同数据源的数据的 FQEP
插入来自不同数据源的数据的 FQEP

在这里,INSERT 操作符没有显示出来,因为它在 Oracle 上。SHIP 操作符没有相关联的语句,因为这个 SHIP 操作符表示将数据从联邦服务器传送到 Oracle。RETURN 操作符中的语句显示了被发送到 Oracle 的语句。

INSERT INTO VALUES "CRDUSER1"."BAD_CREDIT"
("CUSTOMER_ID","CUSTOMER_DEBT") VALUES (:h0 , :h1);

对昵称的数据移动操作

您可以对昵称执行以下数据移动操作。要获得关于用法的详细信息,请参阅 IBM DB2 Universal Database Command Reference (见 参考资料)。

1. 从引用昵称的查询中导出数据
仓库信用调查分析人员想获得 BAD_CREDIT 昵称中债务大于 $10,000 的已有客户的名单。他将这个名单存储在一个名为 bad_customers.del 的定界的 ASCII 文件中。

EXPORT TO bad_customers.del OF del
SELECT customer_id, customer_debt
FROM bad_credit
WHERE customer_debt > 10000;

2. 导入到一个昵称中
仓库信用调查分析人员从管理另一个商店的财务部门收到一个名为 bankrupt.del 的文件。这个文件列出了最近宣布破产的客户以及他们当前的债务。他想将这些内存存储在昵称 BAD_CREDIT 中。

IMPORT FROM  bankrupt.del OF del
ALLOW WRITE ACCESS COMMITCOUNT 20
INSERT INTO bad_credit;

3. 从一个引用昵称的游标装载数据
为了确保全球仓库维护一份有不良信用或破产记录的客户名单,仓库信用调查分析人员创建一个名为 BAD_CUSTOMERS 的本地表。他使用一个分布式查询将信息装载到这个本地表。

DECLARE cursor1 CURSOR FOR 
SELECT x.customer_id, y.customer_name
FROM bad_credit x, customers y
WHERE x.customer_id = y.customer_id;

LOAD FROM cursor1 OF CURSOR INSERT INTO bad_customers;

从游标装载数据也是填充引用昵称的物化查询表(MQT)的一种有效的方法。

使用昵称上的视图

视图是修改数据库对象的一种简单的手段,它使您不必直接与组成视图的物理对象定义打交道。您可以创建引用一个或多个本地表的视图。通过昵称,还可以定义引用来自多个数据源的数据的视图。视图有助于提供更好的数据模型,使用户更容易规划查询。

一个有用的场景是使用 UNION ALL 视图来为合并建模,其中 UNION ALL 操作的每个分支表示来自一个分公司或公司某部门的数据。有了 UNION ALL 视图,就有了来自所有分公司的信息,而这些信息看起来像是在一个表中。下面的例子演示了重写阶段如何提高对 UNION ALL 视图的某些类型的查询,以取得更好的性能。要获得适用于本地表的详细信息,请参阅“Partitioning in DB2 Using the UNION ALL View”(developerWorks,2002 年 2 月,见 参考资料)。

使用联邦 UNION ALL 视图简化查询
这个例子定义仓库昵称上的 UNION ALL 视图。它在每个 NION ALL 视图中的 SELECT 子句上使用一个附加的源列表明数据的来源。当只有来自相同服务器的数据的连接才能产生连接结果时,这一点很有帮助。这些附加的源列,加上用户查询中附加的源连接谓词,可以帮助重写阶段识别不会产生任何连接结果的连接。因此,可以通过消除无效的连接提高性能。

CREATE VIEW items AS
SELECT 'Canada' AS source, x.* FROM canada.items x
UNION ALL
SELECT 'USA' AS source, y.* FROM usa.items y;

CREATE VIEW suppliers AS
SELECT 'Canada' AS source, x.* FROM canada.suppliers x
UNION ALL
SELECT 'USA' AS source, y.* FROM usa.suppliers y;

CREATE VIEW item_supplied AS
SELECT 'Canada' AS source, x.* FROM canada.item_supplied x
UNION ALL
SELECT 'USA' AS source, y.* FROM usa.item_supplied y;

另一种方法是通过在昵称上定义检查约束来指定分区谓词。重写阶段将使用该信息来确定 UNION ALL 分支不相交。

下面展示的附加的视图定义可以帮助您轻松地构造查询。

CREATE VIEW warehouse AS
SELECT i.item_id, i.item_name, i.item_descr,i.item_stocked, s.suppl_id,
suppl_name
FROM items i, suppliers s, item_supplied is
WHERE i.item_id = is.item_id
AND s.suppl_id=is.suppl_id
AND i.source=s.source
AND s.source=is.source;

CREATE VIEW orders_view AS
SELECT o.order_id, o.customer_id, o.order_date, o.order_amount,
i.item_id, i.item_quantity
FROM xml.orders o, xml.order_items i
WHERE o.oid = i.oid;

CREATE VIEW web_orders AS
SELECT a.customer_id, b.customer_name, a.item_id, a.item_quantity,
c.item_descr, c.item_stocked, a.order_date, c.suppl_name
FROM orders_view a, customers b, warehouse c
WHERE a.customer_id = b.customer_id
AND a.item_id = c.item_id;

仓库管理员需要找出那些需要延期发货的商品,以及需要为某个客户联系的供应商。下面的 SQL 语句可以找出客户已经订购的库存低于订购量的商品:

SELECT o.item_id, w.item_descr, o.item_quantity, w.suppl_name
FROM warehouse w, orders_view o
WHERE o.customer_id = '1234512345'
AND o.item_quantity> w.item_stocked;

当提交该查询时,查询编译器会分析它的语法和语义。在此阶段将合并视图定义,以产生一个更复杂的语句,如 图 8 所示。


图 8. 视图展开之后的查询
视图展开之后的查询

接着,重写阶段将把 ORDERS_VIEW 合并到顶层的 JOIN 操作中。然后,通过 JOIN 和 UNION ALL 操作递归地下推合并的操作中的谓词。通过允许将谓词应用到表访问,可以提高性能。下推谓词之后,语句看上去如 图 9 所示。初始的两个 UNION ALL 视图之间的连接操作现在变成了 8 个 JOIN 操作的一个 UNION ALL 操作。


图 9. 通过 Union ALL 下推连接之后的查询
通过 Union ALL 下推连接之后的查询

然后,重写阶段找出 SOURCE 列之间无效的连接。期间会使用源列上的连接谓词,以及在 UNION ALL 视图定义中赋给这些列的值。涉及到跨源数据的连接操作将被删除,因为 SOURCE 列上的连接谓词和视图定义中赋给这些列的值会导致冲突(所以它们不会产生连接结果)。现在语句得到了简化,因为对混合数据源的仓库表的连接操作已经从 图 9 中删除。这个已重写的查询现在如 图 10 所示。


图 10. 删除无用的连接操作之后的查询
删除无用的连接操作之后的查询

图 11 展示了这个查询的一个 FQEP,其中一个远程语句被发送到每个仓库服务器。这里使用了嵌套的循环连接方法来连接来自每个仓库的远程查询结果和 XML 合成视图结果。这里有两个 SHIP 操作符,每个 SHIP 操作符带有一个下推的、三路连接语句。


图 11. 例子查询的 FQEP
例子查询的 FQEP

使用昵称上的信息约束

信息约束可以很好地辅助查询优化。这些规则提供了关于一个昵称各个列存在的关系和约束的更详细的信息。SQL 编译器使用信息约束将语句转化成更优的形式,从而改善对所需数据的访问路径。信息约束有助于提高 WebSphere Information Integrator 联邦系统中的查询性能。

在本系列的 第 1 部分,示例场景定义了以下一组信息约束:

ALTER NICKNAME canada.items ADD CONSTRAINT ck 
      CHECK (item_id BETWEEN '0000000001' AND '5000000000');
ALTER NICKNAME usa.items ADD CONSTRAINT ck 
      CHECK (item_id BETWEEN '5000000001' AND '9999999999');

ALTER NICKNAME canada.item_supplied ADD CONSTRAINT ck1 
      CHECK (item_id) BETWEEN '0000000001' AND '5000000000');
ALTER NICKNAME canada.item_supplied ADD CONSTRAINT ck2
      CHECK (suppl_id) BETWEEN '0000000001' AND '2000000000');

它还定义了以下一组引用约束:

ALTER NICKNAME canada.item_supplied ADD CONSTRAINT fk1 
      FOREIGN KEY (item_id) REFERENCES canada.items  (item_id)
      NOT ENFORCED;
ALTER NICKNAME canada.item_supplied ADD CONSTRAINT fk2
      FOREIGN KEY (suppl_id) REFERENCES canada.supplier (suppl_id)
      NOT ENFORCED;

下面两个例子演示了如何使用那样的约束来简化用户查询和提供更好的性能。

利用检查约束删除无效的 UNION ALL 分支
假设在我们的数据模型中,仓库管理员需要找到 item_id 介于 "2300000000" 和 "3450000000" 之间的商品的名称和描述。

SELECT item_name, item_descr
FROM items
WHERE item_id between '2300000000' and '3450000000';

把该查询提交给 SQL 编译器之后,语义阶段展开视图定义,并将它合并到初始的查询中,如下所示:

SELECT item_name, item_descr
FROM
(SELECT 'Canada' AS source, * FROM canada.items
UNION ALL
SELECT 'USA' AS source, * FROM usa.items)
AS items
WHERE item_id between '2300000000' and '3450000000';

然后,重写阶段应用在这两个昵称上定义的信息约束规则。在这里,定义在昵称 canada.items 和 usa.items 上的检查约束将允许重写阶段删除其中一个 UNION ALL 分支。经过重写变换之后得到的等效的查询如下所示。UNION ALL 视图上的初始查询现在被简化为对一个昵称的查询。

SELECT item_name, item_descr
FROM canada.items
WHERE item_id between '2300000000' and '3450000000';

利用检查约束和引用约束删除无效连接
接下来的例子展示了如何在更复杂的例子中使用检查约束和引用约束。下面的 SQL 语句将检索关于由供应商 ID 介于某个范围的供应商所供应的商品的信息。

SELECT b.*
FROM items a, item_supplied b
WHERE a.item_id= b.item_id
AND a.source = b.source
AND b.suppl_id between '1000000000' and '1230000000';

视图展开之后,items 和 item_supplied 视图将在查询中合并,如 图 12 所示。


图 12. 视图展开之后的查询
视图展开之后的查询

接下来,重写阶段将通过 UNION 操作下推连接,并删除无用的连接。这种变换在前面几节中已经解释过。图 13 图形化地显示了该语句。


图 13. 下推连接和删除无用连接之后的查询
下推连接和删除无用连接之后的查询

图 13 所示,连接和本地谓词现在在昵称之上。重写阶段将使用四个昵称上定义的引用约束和检查约束来删除连接操作和一个 UNION 分支。引用约束用于删除连接,而检查约束用于删除 UNION 分支。下面展示的最终的等效查询显然比初始的查询更简单,性能也更佳。

SELECT *
FROM canada.item_supplied
WHERE suppl_id between '1000000000' and '1230000000';

缓存昵称数据

可以通过定义物化查询表(Materialized Query Tables,MQT)—— 以前称为自动总结表(Automatic Summary Tables,AST)—— 来在本地缓存引用关系和非关系昵称的查询的结果。在到那些数据源的网络通信较慢,并且可以接受适度陈旧的数据的情况下,这一点很有帮助。您不需要修改应用程序中的查询。联邦系统检测查询的哪个部分可以用一个特定的 MQT 来回答,使用 MQT 而不是昵称是否能使查询执行得更快。

定义 MQT 的另一个好处是,如果查询只通过 MQT 来回答(没有远程请求),那么数据源的可用性不再是问题,因为用本地缓存的数据就可以回答查询。

目前,增量更新(incremental update)—— 当底层对象被修改时更新 MQT 的一种机制 —— 还不能用于引用昵称的 MQT。

您可以通过定义适合于工作负载的 MQT 来提高联邦工作负载的性能。在 WebSphere Information Integrator 系统中可以定义两种类型的 MQT:

  1. 系统维护的 MQT
  2. 用户维护的 MQT

下面的例子展示了一个系统维护的 MQT,以便阐释在定义 MQT 和启用到 MQT 的路由的语法和步骤。

想像一下,如果您经常需要查找提供一些在加拿大流行的商品的供应商的名称和地址,将会是怎样的情景。

步骤 1:您可以像下面这样定义一个 MQT:

CREATE TABLE popular_item_suppliers(item_id, suppl_id, suppl_name, suppl_address) AS
   	(SELECT i.item_id, s.suppl_id, s.suppl_name, s.suppl_address
   	FROM canada.item_supplied i, canada.suppliers s
   	WHERE i.suppl_id = s.suppl_id
   	AND i.item_id IN ('1234567890','2345678901','3456789012','4567890123'))
DATA INITIALLY DEFERRED REFRESH DEFERRED 
ENABLE QUERY OPTIMIZATION
MAINTAINED BY SYSTEM;

步骤 2:注意,引用昵称的系统维护的 MQT 必须定义为 REFRESH DEFERRED。那样的 MQT 只能通过刷新整个表来维护。您可以执行以下语句来填充这个 MQT:

REFRESH TABLE popular_item_suppliers;

步骤 3:这时,您可能需要考虑在 MQT 上定义索引。您还应该考虑在 MQT 上执行 runstats,以便查询优化器拥有关于 MQT 中的行数以及其他统计信息的准确信息。

步骤 4:在发出查找一件流行商品的供应商的查询之前,将 refresh age 设置为 'ANY'。这样便指示联邦系统,您愿意容忍陈旧的结果。

SET CURRENT REFRESH AGE any;

当发出下面的查询时,查询优化器将检测到该查询可以用一个 MQT 来回答,因而可能会选择访问该 MQT 的一个访问计划。

SELECT i.item_id, s.suppl_id, s.suppl_name
FROM canada.item_supplied i, canada.suppliers s
WHERE i.suppl_id = s.suppl_id
AND i.item_id = '1234567890';

为了检查查询是否确实被路由到 MQT,您可以使用 SQL Explain 实用程序获得由优化器选择的 Query Execution Plan,并在计划中查找 MQT 访问。

与系统维护的 MQT 不同,您可以通过装载、插入、导入或复制(后面会描述)来使用户维护的 MQT 保持最新。在具有数据分区功能的联邦系统中,只能定义用户维护的 MQT。下面是定义和使用用户维护的 MQT 的过程:

步骤 1:创建 MQT。

CREATE TABLE popular_item_suppliers(item_id, suppl_id, suppl_name, suppl_address) AS
   	(SELECT i.item_id, s.suppl_id, s.suppl_name, s.suppl_address
   	FROM canada.item_supplied i, canada.suppliers s
   	WHERE i.suppl_id = s.suppl_id
   	AND i.item_id IN ('1234567890','2345678901','3456789012','4567890123'))
DATA INITIALLY DEFERRED REFRESH DEFERRED 
ENABLE QUERY OPTIMIZATION
MAINTAINED BY USER;

步骤 2:使用从游标语句或插入语句发出的装载为 MQT 填充数据。'refresh table' 命令在用户维护的 MQT 上不受支持。

步骤 2b:这个步骤是用户维护的 MQT 特有的。CURRENT MAINTAINED TABLE TYPES 专用寄存器控制被考虑用于路由的 MQT 的类型。例如,下面的命令将迫使查询优化器考虑使用用户维护的 MQT 来回答查询:

SET CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION USER;

要学习如何用这种专用寄存器包括其他类型的 MQT,请参阅 IBM DB2 Universal Database SQL Reference (见 参考资料)。

下面的命令使用户维护的 MQT 脱离检查暂挂状态,并启用它,以便进行优化。

SET INTEGRITY FOR  popular_item_suppliers ALL IMMEDIATE UNCHECKED;

您可以使用前面为系统维护的 MQT 列出的步骤 3 和 4 来启用到用户维护 MQT 的路由。

DB2 Design Advisor 可以给出关于创建新 MQT 的建议。要了解关于如何使用 DB2 Design Advisor 推荐 MQT 的详细信息,请参阅 IBM DB2 Universal Database Administration Guide: Performance (见 参考资料)。

下面是关于 Design Advisor 的一些提示和限制:

  1. 由于只能在昵称上创建 'refresh deferred' MQT,您需要带 '-u' 选项调用 Design Advisor。如果不指定 '-u' 选项,那么 Design Advisor 不会返回建议。
  2. 在具有数据分区功能的联邦系统中,对于昵称只支持用户维护的 MQT。系统维护的 MQT 不受支持。为了使用系统维护的 MQT,需要编辑 Design Advisor 给出的建议中的语法。
  3. 除了上面的限制外,对于非关系昵称上的 MQT,定义 MQT 的 SQL 语句对于涉及的非关系数据源必须是合法的。例如,一个 Blast 数据源需要 BlastSeq 列上的一个等于谓词。像 'select * from blast_nickname' 这样的语句将被 Blast 服务器拒绝。所以,如果 MQT 是用那样的语句创建的,那么 REFRESH TABLE 语句将失败。关于这些类型的非关系约束,请参阅 IBM DB2 Information Integrator Data Source Configuration Guide (见 参考资料)中关于各数据源的部分。

除了使用插入或装载操作手动地刷新 MQT 之外,WebSphere Information Integrator 还允许使用 缓存表(cache table) 机制通过 Control Center 创建使用单个远程对象的简单 MQT,并让您设置复制,以便自动化 MQT 的刷新。关于缓存表的更多细节请参阅 IBM DB2 Information Integrator Federated Systems Guide (见 参考资料)。





回页首


联邦查询性能调优

本节主要关注联邦系统中查询性能的调优。在调优查询性能之前:

  1. 为应用程序堆、语句堆、缓冲池和临时表空间这些区域中的本地处理调优联邦系统。另外还配置联邦系统,以便执行高效的本地连接和排序操作。考虑使用 AUTOCONFIGURE 命令来发现 DB2 Configuration Advisor 提供的建议。要获得更多细节,请参阅 IBM DB2 Universal Database Command Reference (见 参考资料)。DB2 快照监视器是一个非常有帮助的工具,它可以提供系统的全局视图。您可以使用快照来获得诸如缓冲池命中率、排序堆溢出的次数以及系统工作负载之类的信息。关于系统调优和快照监视器的更多细节,请参阅 IBM DB2 Universal Database Administration Guide: Performance (见 参考资料)。
  2. 如果您的联邦系统需要用 ODBC 包装器访问一个数据源,那么您可能需要考虑检查服务器选项 PUSHDOWN。该选项表明联邦服务器是否应该考虑下推对一个关系数据源的任何 SQL 操作。也就是说,当对于一个数据源它被设为 'N' 时,联邦服务器只发送类似于 SELECT column_list FROM table 的远程请求,这会影响性能。对于除 ODBC 数据源之外的所有关系数据源,默认的设置是 'Y'。如果数据源可以处理谓词之类的基本操作,那么考虑将该选项设为 'Y'。
  3. 如果联邦系统使用了数据分区功能,那么考虑将包装器选项 'DB2_FENCED' 设置为 'Y',以便允许多个节点处理昵称数据,从而更好地利用分区间(inter-partition)并行性。要获得更多细节,请参阅“WebSphere Information Integrator V8.2 中的并行性”(developerWorks,2005 年 2 月,见 参考资料)。
  4. 请访问 第 1 部分: 设计和配置,以获得关于提高性能的建议。您可能需要在服务器上、昵称上和昵称列上进行定制(请参阅 IBM DB2 Information Integrator Federated Systems Guide 以获得更多信息)。

下面是用于调优联邦查询性能的众多方法中的一种。“在多个数据源的 J2EE 环境中的 DB2 Information Integrator 性能”(developerWorks,2003 年 6 月)和 Data Federation with IBM DB2 Information Integrator V8.1(见 参考资料)可以作为这一话题的参考资料。下面的例子表明,知道应识别的一系列问题,比知道解决这些问题的确切顺序更加重要。图 14 展示了当您开始性能评价阶段时,要问的第一组问题:

步骤 1.1:检查查询执行时间
DB2 快照监视器和 db2batch 这两个工具可以以不同的详细程度报告查询的执行时间。您可以使用它们来确定:

  • 用于编译和执行查询的时间是否可以接受。
  • 联邦服务器所花费的时间是否与直接在数据源(涉及单个数据源的查询中的数据源)上执行查询时所花的时间相当。
  • 联邦系统的性能是否与一些已有的用户编写的实现相同分布式查询的应用程序的性能相当。

您可以使用 DB2 快照监视器监视联邦系统的各个元素。关于这里监视的联邦数据库系统的元素的列表,请参阅 IBM DB2 Universal Database System Monitor Guide and Reference (见 参考资料)。此外,您可以专门为联邦查询片段打开监视器,以帮助您理解联邦系统如何处理查询。要获得更详细的信息,请参阅 IBM DB2 Information Integrator Federated Systems Guide (见 参考资料)。


图 14. 第 1 阶段的性能调优
第 1 阶段的性能调优

步骤 1.2:收集昵称的统计信息
目前,RUNSTATS 命令对于昵称而言还不受支持。联邦系统在创建昵称时收集关系昵称(和一些非关系昵称)的统计信息。运行与 RUNSTATS 等效的其他工具来收集关于远程数据的统计信息也是很好的做法。如本系列 第 1 部分 中的“昵称统计信息”小节所述,如果底层的远程对象的统计信息可能已经发生了变化,那么可以通过 Control Center 运行昵称更新统计信息实用程序,或者从 CLP 中调用 SYSPROC.NNSTAT 存储过程。查询优化器很大程度上依赖于这些统计信息 —— 尤其是 card、colcard、high2key 和 low2key。有了准确的统计信息,查询优化器就更有可能产生好的计划。对于难以从编目中获取统计信息的远程对象上的昵称,WebSphere Information Integrator 还提供了一个名为 getstats 的可执行文件,该文件对数据源运行 SQL 语句,以收集统计信息,并相应地更新联邦系统上的昵称统计信息。

步骤 1.3:定义索引
在数据源上的远程表上定义索引有时候可以提高查询性能。如果为已经有一个昵称的远程数据源上的远程对象创建新索引,那么可能需要或者为新索引定义索引规范,或者删除并重新创建昵称,以便联邦系统编目能反映新的索引信息。有时候,您可能发现还可以通过定义附加的索引规范来提高性能。要了解更多关于创建索引规范的信息,请参阅 IBM DB2 Universal Database SQL Reference (见 参考资料)。

步骤 1.4:定义 MQT
如果到远程数据源的网络通信较慢,并且适度陈旧的数据是可以接受的,那么定义 MQT 有助于提高性能。请参阅关于物化查询表的小节。

步骤 2.1:检查查询执行计划
您可以使用 Visual Explain 或 db2exfmt 的输出来获得查询执行计划。关于如何解释 FQEP 的详细说明可以在“解释联邦查询执行计划”小节中找到。

步骤 2.2:查找远程操作符
检查 db2exfmt 输出或 Visual Explain 输出,以发现语句中远程计划操作符(用于 SELECT 的 SHIP 或 RPD 操作符以及用于 INSERT/UPDATE/DELETE 的 RETURN 操作符)的位置和数量。检查每个远程操作符是否包含在理论上可由给定数据源计算的查询中的最大部分。检查 db2exfmt 或 Visual Explain 输出中经过优化的 SQL,因为这是关系数据源下推分析和查询优化器确定计划的基础。必要时,可以试着重写查询,看看它如何影响优化的 SQL。


图 15. 第 2 阶段的性能调优
第 2 阶段的性能调优

步骤 2.3:考虑 DB2_MAXIMAL_PUSHDOWN 服务器选项
考虑设置这个服务器选项,以便将尽可能多的工作下推到远程数据源。查询优化器将尝试减少发送到数据源的消息的数量。如果查询中存在来自多个数据源的昵称,那么可以选择为某些服务器设置 DB2_MAXIMAL_PUSHDOWN,而为其他服务器重置该选项,这取决于远程查询优化器的能力,所使用的机器,等等。当设置了该选项时,查询优化器选择按照 PDA 的指示将大部分工作下推到数据源的查询执行计划。对于涉及到 MQT 的执行计划,并且该 MQT 是涉及远程表访问的计划上的 MQT,查询优化器给予它优先权。

步骤 2.4:寻找其他下推机会
为了减少从远程数据源取数据的次数,可以检查在联邦系统本地计算的谓词是否可以发送到远程数据源。类似地,您可以判断在本地执行的任何 GROUP BY 或 DISTINCT 操作符是否可以在远程数据源上执行。您可能需要在联邦服务器上执行更多的定制,以便允许更多的操作可以考虑在远程执行。这些定制可包括添加缺失的函数映射、修改昵称列的数据类型以及设置某些与性能相关的选项。

联邦系统还提供了三个服务器选项,用于调整关系数据源的远程成本,这三个选项是:CPU_RATIO、IO_RATIO 和 COMM_RATE。CPU_RATIO 和 IO_RATIO 表示处理器速度和远程数据源上的输入/输出率与联邦系统的比率。默认情况下,这个比率为 1.0,意即处理速度是相同的。COMM_RATE 表示网络带宽。如果您想将更多的工作下推到远程数据源(没有设置 DB2_MAXIMAL_PUSHDOWN),那么可以修改这些比率,以鼓励查询优化器利用远程数据源上的更快的 CPU 和 I/O。如果网络较慢,查询优化器还尝试减少发送到数据源的消息数量。大多数联邦系统用户不需要调优这三个选项,因为默认值已经相当好了。

步骤 2.5:验证选择性估计
查询中谓词的选择性决定了查询执行计划中不同位置的基数(行数)。这个基数会大大影响连接顺序和连接方法。而连接方法和连接顺序的选择反过来又会影响计划的质量。如果有了准确的统计信息,那么查询优化器一般能够得出正确的选择性估计。有时候,由于在数据分布上的一点偏差,加上谓词或查询的特性,或者由于统计信息不充分,可能导致优化器的选择性估计不准确。这可能导致选择性能不佳的计划。关于选择性子句的更多信息,可以在“使用 SELECTIVITY 子句影响优化器”(developerWorks,2004 年 2 月,见 参考资料)中找到。


图 16. 第 3 阶段的性能调优
第 3 阶段的性能调优

步骤 3.1:配置块读取 block fetching
块读取(block fetch)对于减少联邦系统与远程数据源之间的消息数量很有帮助。默认情况下,块读取是被启用的。数据库管理器参数 rqrioblk 控制着联邦系统与数据源之间的通信缓冲区的大小。考虑像下面描述的那样调整这个设置,以帮助提高性能。

然而,有些查询本身可能是潜在的更新目标(例如只引用最外面的 SELECT 上的一个昵称的查询)。当检测到一个潜在的更新目标时,联邦系统避免使用块读取特性,以维护远程游标的位置。由于这个原因,您应该将 'FOR FETCH ONLY' 子句加在不会成为更新目标的查询的后面,或者使用 'BLOCKING ALL' 作为应用程序的一个绑定选项。当返回的某一行很大时,可能不能激活块读取。例如,如果返回的行大于 32K 字节,并且 rqrioblk 也设置在 32K 字节(默认情况) ,那么每一行将分两个块返回。这样便不能看到块读取的效果。在这个例子中,将 rqrioblk 参数值增加到 64K 有助于提高性能。

步骤 3.2:考虑优化前几行
通常,查询优化器选择将在最短时间内返回整个结果集的计划。如果您只想看到查询结果的前几行,而不需要等到整个结果集都返回,那么 OPTIMIZE FOR N ROWS 子句提供了性能调优的机会。查询优化器可能得出一个不同的查询执行计划,这个计划可以专门为最快地获取前 'N' 行,而不是所有结果行提供良好的性能。

步骤 3.3:检查远程计划
对于通过使用类似于 EXPLAIN 的实用程序发送到每个数据源的远程语句,应该检查远程计划。查询优化器有可能生成与远程服务器的性能限制有冲突的远程语句。在这种情况下,请与 IBM 服务团队联系。如果远程计划不是最优的,那么应该与远程数据源的系统管理员联系,以便调查性能问题。





回页首


结束语

随着使用 WebSphere Information Integrator 作为集成平台的用户越来越多,这个由两部分组成的系列提供了很多关于构建和使用联邦系统的指南。重要的是,我们要继续与客户紧密合作,增强数据联邦技术。即使我们为今天有竞争力的性能优势而骄傲,我们也仍将继续致力于性能的提高。我们将一如既往地争取提供更多的执行分布式查询的方案。由于分布式查询性能问题的诊断非常复杂,我们还将致力于开发能简化这一工作的工具。请继续关注吧,后面还有更多的东西呈献给您。



参考资料



作者简介

作者照片

Anjali Betawadkar-Norwood 是坐落在加利福尼亚州圣何塞市的硅谷实验室的一名顾问软件工程师。她的专长是 Query Optimization,尤其是将其应用于联邦系统。她在查询优化领域有五年的工作经验。目前,她领导一个小组专攻 WebSphere Information Integrator Federated Query Compiler 中的联邦查询优化。


作者照片

Dr. Eileen Lin 是坐落在加利福尼亚州圣何塞市的硅谷实验室的一名高级技术员工。她是负责 DataJoiner 的最早成员之一,DataJoiner 是一种联邦数据库产品,也是 DB2 中联邦技术的前驱。目前,她正担任 WebSphere Information Integrator 中这种技术的架构师。Dr. Lin 拥有很多专利,涵盖的领域有联邦技术、查询优化和并行查询处理等。


作者照片

Ioana Ursu 是坐落在加利福尼亚州圣何塞市的硅谷实验室的一名高级软件工程师。她于 1998 年加入 IBM Almaden,从事 Garlic 研究项目方面的工作。从 1999 开始,她从事过联邦查询编译的很多领域,包括查询语义、查询重写、下推分析和查询优化。目前她在 WebSphere Information Integrator Federated Query Compiler 小组工作,主要从事通用联邦查询处理方面的工作。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?







回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款