很多DBA第一次接触DB2联邦(Federation)这个功能时,第一反应是“这不就是分布式数据库吗”,第二反应是“那我直接连源库查不就行了”。这两个反应我都经历过,实际在银行、制造业的项目里摸爬滚打之后,才真正把联邦的定位和使用边界搞清楚。这篇文章不打算抄官方文档,而是从实际施工的角度,拆解DB2联邦的核心概念、架构对象、配置流程和那些文档里不会明说的坑。如果你正在考虑通过联邦整合多个数据库,或者已经被领导安排去调研跨库查询方案,这篇文章应该能帮你少走几步弯路。
1. 联邦到底解决什么问题:先搞清楚它“能”和“不能”
1.1 没有联邦之前,跨库访问有多折腾
在很多老系统里,数据分散是常态。核心交易在Oracle,历史归档在DB2,报表库在SQL Server,偶尔还得从Excel文件里取数。业务方说“帮我拉一份上个月所有渠道的交易明细,关联一下客户等级”——听起来一句话,做起来就麻烦了。
传统做法无非几种:要么用ETL工具把多个源的数据抽到一张汇总表,要么在应用层写Java代码分库查完再内存里关联,要么靠DBA手工导数据。ETL的问题在于时效性差,今天的数据明天才能看到;应用层关联的问题在于SQL没法做数据库层面的优化,数据量大一点就内存溢出;手工导数据就更别说了,一次两次还行,天天导谁也受不了。
更麻烦的是数据一致性。多个系统之间时间窗口对不上,各抽各的,最终对账的时候差出来几万条记录,没人说得清是哪个环节漏了。
1.2 联邦方案的核心价值
DB2联邦通过在一台DB2实例上创建远程数据源的映射对象,让本地用户可以像查询普通本地表一样,用一条标准SQL跨多个异构数据库取数。对应用层完全透明,不需要改代码,不需要引入中间件,也不需要同步数据。
它的核心价值就是:实时、无损、统一入口。
- 实时:查询直接打到远端数据库,数据是最新的,没有同步滞后。
- 无损:不拷贝数据,不占额外的存储空间,不存在“两边的数据不一致”的问题。
- 统一入口:应用只连DB2,所有跨源查询都在数据库层完成,安全权限、审计也都在一个地方控制。
从这个角度说,联邦解决的不是“大数据量存储”的问题,而是“多源实时整合”的问题。理解这一点非常重要,因为后面你判断某个需求能不能用联邦来解决时,判断标准就清晰了——需要实时跨源取数的,适合联邦;需要把历史数据压缩归档长期保存的,那是数据仓库的活,不是联邦该管的。
2. 联邦架构拆解:从WRAPPER到NICKNAME,四个对象弄懂整套机制
2.1 WRAPPER:数据源类型的翻译器
联邦要连接不同的数据库,首先要解决“语言不通”的问题。DB2不认识Oracle的SQL方言,也不认识SQL Server的T-SQL,所以需要一层转换层——这就是WRAPPER(包装器)。
可以把它理解成一个电源转换头。你从中国带了一个双孔插头的笔记本去欧洲,墙上的插座是圆孔的,直接插不进去,需要一个转换头。WRAPPER就是这个转换头,它负责把DB2的SQL请求,翻译成目标数据库能听懂的方言,再把结果翻译回DB2的格式。
DB2内置了几类常见的WRAPPER,我列个表说明:
| Wrapper类型 | 可连接的数据源 | 说明 |
|---|---|---|
| DRDA | DB2 for LUW、DB2 for z/OS、DB2 for i | 连DB2家族首选,效率最高 |
| SQLJ | 通过JDBC连接任意支持JDBC的数据库 | 灵活但性能比DRDA略低 |
| ORACLE | Oracle数据库 | 需要装Oracle客户端库 |
| SQLSERVER | SQL Server | 走SQL Server原生协议 |
| ODBC | 支持ODBC标准的数据库/文件 | 比如Access、甚至某些NoSQL的ODBC驱动 |
注意:创建WRAPPER时,DB2实例需要安装对应的客户端库。比如要连Oracle,DB2服务器上必须装了Oracle Instant Client,否则WRAPPER能建成功,但一查询就报“不能加载共享库”。
我第一次配置Oracle联邦时就在这里卡了整整一天,日志一直提示找不到libclntsh.so,后来发现是没把Oracle客户端库路径加到LD_LIBRARY_PATH环境变量里。这个在官方文档里只有一句话,实际操作中却是最常见的第一坑。
2.2 SERVER与USER MAPPING:远端连接的登记与认证
有了WRAPPER,DB2知道了怎么跟对方“说语言”,但还不知道“对方在哪、门牌号是多少”。这就需要创建SERVER对象。
SERVER对象定义的是远端数据库的实际连接信息:主机地址、端口号、数据库名、字符集等。这些信息相当于给对方数据库建立了一份“档案”。
然后是USER MAPPING(用户映射)。这里值得单独拎出来讲,因为很多初学者会忽略它的作用。
DB2联邦的认证机制是:本地用户查询托管表时,DB2需要以某个远端用户的身份去连接远程数据库。USER MAPPING就是定义“本地用户→远程用户”的对应关系。
比如本地用户APP_DBA查询Oracle上的昵称时,DB2会使用ORA_REMOTE_USER这个Oracle账号去建立连接,这个Oracle账号的密码加密存在DB2的密码库中。在Oracle侧,你只需要给这个账号授予查询特定表的权限就够了,不需要给DBA权限。这是联邦安全模型的关键——最小权限原则。
创建用户映射的SQL长这样:
CREATE USER MAPPING FOR APP_DBA SERVER ORA_PROD_SERVER OPTIONS (REMOTE_AUTHID 'ORA_REMOTE_USER', REMOTE_PASSWORD 'EncryptedPwd@123');注意REMOTE_PASSWORD这里虽然是明文的,但DB2内部会用加密方式存储,通过db2 get dbm cfg或系统表查询是看不到明文密码的。这个机制保证了即使有人拿到了数据库的连接权限,他也拿不到远端数据库的密码。
2.3 NICKNAME:远端表的本地投影
前三个对象都配好之后,还差最后一个关键动作——创建NICKNAME(昵称)。
NICKNAME是一个本地逻辑对象,它映射到远端数据库的一个具体表或视图。创建了NICKNAME之后,你就能在SQL里直接SELECT * FROM NICKNAME,而这个查询实际执行时,会翻译成对远端数据库的访问。
CREATE NICKNAME ORA_CUSTOMER FOR ORA_PROD_SERVER.ORA_REMOTE_USER.CUSTOMERS;注意这里的三段式命名:SERVER名.远端Schema名.远端表名。很多人在这里踩坑,把第二段写成远端数据库实例名,正确写法是远端Schema(在Oracle里就是用户,在SQL Server里是Schema,在DB2里是Schema)。
创建好NICKNAME后,可以用以下命令查看映射关系:
SELECT * FROM SYSCAT.NICKNAMES;理解了这四个对象的关系,联邦的整个架构就清晰了:
WRAPPER解决“语言”问题,SERVER解决“地址”问题,USER MAPPING解决“身份”问题,NICKNAME解决“表映射”问题。
四个对象层层递进,缺一不可。底层原理搞明白了,后面配置的时候就算遇到报错,也能根据自己的逻辑去推断是哪个环节出了问题。
3. 查询下推:为什么有的联邦SQL快,有的慢到怀疑人生
3.1 下推(Pushdown)的基本逻辑
联邦查询在DB2里的处理流程是这样的:用户发出一条SQL,DB2联邦优化器会分析这条SQL,决定哪些部分可以“下推”到远端数据库执行,哪些部分必须拿到本地来算。
所谓下推,就是把SQL里的部分操作(比如WHERE过滤、JOIN、聚合、排序)直接发到远端数据库,让远端数据库先处理完,再把处理结果返回给DB2。核心理念是:尽量减少跨网络传输的数据量。
举个例子——
SELECT c.customer_id, c.name, o.order_amount FROM ORA_CUSTOMER c INNER JOIN LOCAL_ORDER o ON c.customer_id = o.customer_id WHERE o.order_date > CURRENT_DATE - 30 DAYS AND c.customer_region = '华东';这条SQL里,ORA_CUSTOMER是Oracle上的昵称,LOCAL_ORDER是本地表。DB2优化器可能会把c.customer_region = '华东'这个谓词下推到Oracle层去执行,Oracle先过滤掉非华东地区的客户,只把符合条件的记录返回给DB2;而LOCAL_ORDER的过滤和两张表的JOIN,则在DB2本地完成。
这个设计的精妙之处在于:不是所有操作都适合下推,优化器会基于统计信息和成本模型,选择一个总代价最小的执行计划。
3.2 哪些操作能下推,哪些不能
不是所有SQL操作都能下推。下面是我在实际项目中总结的经验:
常驻可下推的操作:
- 简单列投影(SELECT指定列)
- 等值谓词过滤(
WHERE col = value) - 排序(ORDER BY)
- 部分聚合(COUNT、SUM、AVG、MIN、MAX)
- 部分连接(如果JOIN双方都在同一个远端数据源)
通常不下推的操作:
- 本地函数(比如DB2自定义函数UDF)
- 非确定型函数(如
RAND()) - 跨异构数据源的JOIN(比如Oracle的表和SQL Server的表做JOIN,这个只能拉到DB2本地做)
- 部分特殊的日期/时间函数,各数据库实现差异大,下推容易出错
关键点:联邦查询的性能好坏的80%取决于你写SQL时有没有刻意“配合下推”。你写WHERE条件时,如果对昵称表做函数运算,比如WHERE UPPER(c.name) = 'ABC',这个UPPER()函数如果远端不支持同名函数,优化器就不会下推这个谓词,整表拉回来本地过滤——性能立刻崩。
我在一个项目里就遇到过类似问题。联邦查询Oracle的订单表,业务方为了兼容大小写,写了个WHERE UPPER(status) = 'COMPLETE',结果Oracle那边几百万行全部拉到DB2本地算,查询跑了3分钟。改成WHERE status = 'COMPLETE'(让Oracle侧索引生效)之后,查询降到毫秒级。
所以,写联邦SQL的时候,脑子里要时刻有“这下推吗?”这根弦。规则很简单:谓词、连接、排序、分组能不下推就不下推(指不要用函数包裹列),尽量直接让远端数据库的索引发挥威力。
3.3 数据类型的隐性转换:一个容易忽略的大坑
联邦查询里,本地表字段类型和远端表字段类型的匹配,是另一个容易被忽略的性能杀手。
DB2联邦支持大多数基础数据类型的透明映射,但细节之处有坑。比如Oracle的NUMBER(18,2)映射到DB2的DECIMAL(18,2),一般没问题;但Oracle的DATE类型映射到DB2,如果不做处理,会变成TIMESTAMP。这本身不算错,但如果你在JOIN条件里把TIMESTAMP和本地表的DATE比较,优化器可能会因为数据类型不匹配,放弃某些索引优化。
更坑的是字符集。Oracle的VARCHAR2(100 CHAR),如果数据库字符集是AL32UTF8,DB2侧对应VARCHAR(400)还不够,因为四个字节存一个中文字符,有些情况下需要VARCHAR(1000)。我见过一个项目,昵称表建好后,查询中文字段返回乱码,排查了一整天,最后发现是CREATE NICKNAME时没有指定列对应的字符长度映射,DB2按字节数做转换导致截断。
解决办法是在创建昵称之前,先仔细核对远端表的字段类型,必要时用视图包装一层,把字符类型在远端就转成合适的长度,再建昵称。
4. 实操配置:一步一步把两个数据库“联邦”起来
4.1 前置条件:FEDERATED配置参数开启
很多教程跳过了这一步,直接开始建Wrapper,结果报错“FEDERATED is not enabled”。
DB2实例默认是没有启用联邦功能的。你需要在DB2实例上执行:
db2 update dbm cfg using FEDERATED YES这个命令修改的是DBM(Database Manager)级别的配置,改完后要重启实例才生效:
db2stop force db2start这一步是新手翻车重灾区,因为报错信息很可能只写“SQL1117N”,字面意思是“命令不能执行的状况”,完全不提FEDERATED没开,你得看db2diag.log才能找到真正的原因。所以一定要先确认所有前置条件,再开始后面的操作。
确认是否开启:
db2 get dbm cfg | grep -i federated输出Federated Database Support = YES才算成功。
另外,连接Oracle需要使用Oracle客户端库,DB2服务器上需要安装Oracle Instant Client(最低版本一般建议11.2以上),并确保LD_LIBRARY_PATH包含了客户端库目录,否则建Wrapper时报SQL1598N或SQL30020N之类的问题。
4.2 完整的联邦创建流程(以连Oracle为例)
假设场景:DB2实例已经运行,需要联邦到一个Oracle数据库。Oracle信息如下(举例):
- 主机:192.168.1.10
- 端口:1521
- 服务名:ORCLPDB
- Schema:ORA_APP
- 要访问的表:ORA_APP.CUSTOMERS
步骤一:创建WRAPPER:
CREATE WRAPPER "WR_ORA" LIBRARY 'libdb2o.so' OPTIONS (FENCED 'Y');连Oracle时,LIBRARY参数一般写libdb2o.so。如果连的是DB2系列,用DRDA库:
CREATE WRAPPER "WR_DRDA" LIBRARY 'libdb2drda.so' OPTIONS (FENCED 'Y');FENCED参数的含义是,Wrapper在独立进程中运行,不直接占用DB2引擎进程的内存空间。这样配置的好处是,远端连接异常时,进程崩溃不会波及DB2主引擎。代价是进程间通信有微小开销,但对绝大多数场景可以忽略。
步骤二:创建SERVER:
CREATE SERVER "ORA_PROD" TYPE ORACLE VERSION 12.2 WRAPPER "WR_ORA" OPTIONS (NODE '192.168.1.10', PORT '1521', DBNAME 'ORCLPDB', PUSHDOWN 'Y');PUSHDOWN 'Y'是默认值。这个选项决定是否允许优化器下推操作到远端。除非有特殊的排查需求,建议保持Y。如果改成N,所有过滤、聚合、排序都在DB2本地做,跨网络数据量会爆炸,性能惨不忍睹。
步骤三:创建USER MAPPING:
CREATE USER MAPPING FOR DB2_LOCAL_USER SERVER "ORA_PROD" OPTIONS (REMOTE_AUTHID 'ORA_APP', REMOTE_PASSWORD 'Oracle_Pwd123');注意第一个FOR后面跟的是本地的DB2用户(或PUBLIC),REMOTE_AUTHID是Oracle侧的用户名。Oracle侧的这个用户只需要必要的表权限,绝不要给DBA。
步骤四:创建NICKNAME:
CREATE NICKNAME ORA_CUSTOMERS FOR "ORA_PROD"."ORA_APP"."CUSTOMERS";然后就可以查询了:
SELECT COUNT(*) FROM ORA_CUSTOMERS WHERE CUSTOMER_REGION = '华东';按照上面的配置,这个COUNT和WHERE应该会下推到Oracle执行,返回的结果只是一个数字。你可以通过db2expln或者查看执行计划来验证下推是否成功。
4.3 用PASSTHRU做特殊操作
有些情况下,你需要在远程数据库执行一个DB2无法表达的操作(比如调用Oracle的某个专用函数、执行存储过程),这时可以用PASSTHRU模式。
SET PASSTHRU ORA_PROD; -- 此时你写的SQL会原样发送到Oracle执行 SELECT * FROM user_tables; SET PASSTHRU RESET;这个功能属于联邦里的“直通后门”,灵活性极高,但也要警惕:PASSTHRU模式下DB2不做语法校验,也不做任何优化,纯透明转发,如果权限管控不当,本地用户可能通过直通模式执行了权限之外的远端操作。生产环境建议严格限制PASSTHRU的使用范围,只开放给DBA账号。
5. 性能优化与安全加固:联邦用久了才会注意到的细节
5.1 统计信息和缓存:为什么联邦查询第一次慢,第二次快
联邦查询第一次执行往往很慢,第二次、第三次就快了。这里有两个原因:
一是DB2联邦优化器需要获取远端表的数据分布信息来做优化决策。第一次查询时,它会向远程数据源发送一些统计信息请求,这些信息会缓存在本地系统表里。如果远端表数据量变化很大,你不刷新统计信息,优化器可能会基于过期的统计信息做出错误的执行计划。
维护方式是用REFRESH NICKNAME命令:
REFRESH NICKNAME ORA_CUSTOMERS;这个命令会重新获取远端数据源的元数据和统计信息。建议在远端表结构变更(加列、删列、改类型)后,必须执行一次REFRESH NICKNAME,否则本地昵称的结构还是旧的,查询可能报列不存在,或者更糟——列对错位。
二是因为数据库连接复用。DB2会复用与远程数据源之间的连接。首次查询要做TCP握手、认证等开销,后续连接复用后开销大幅下降。
另一个缓存参数是DB2_FED_FULLPUSHDOWN和DB2_FED_NICKNAME_CACHE。后者是环境变量,控制昵称元数据的缓存大小,在连接数高、昵称多的时候适当调大,能降低反复获取元数据带来的开销。
以我接触过的某个生产系统为例,有400多个联邦昵称,默认缓存值不够,每5分钟就出现一次元数据重取的性能尖刺,调大DB2_FED_NICKNAME_CACHE之后大幅缓解。
5.2 远端连接池与并发控制
每次联邦查询都会消耗一个到远端数据源的连接。如果并发用户很多,DB2会向远端数据库建立大量连接,可能会压垮远端的连接数限制(比如Oracle的PROCESSES参数)。
DB2实例参数FEDERATED_ASYNC控制联邦连接的异步建立方式,但更关键的其实是数据库参数MAXAGENTS、NUM_POOLAGENTS这些。在实际项目中,我更推荐的做法是:
- 在远端数据库侧做好连接数监控,给联邦用户单独设置PROFILE限制,避免一个应用把远端的连接数全占光。
- 本地DB2侧合理配置连接池,减少频繁建连。
- 如果只是每天跑批需要用联邦,可以限时段连通。
还有一个容易忽略的安全点:通过联邦访问远端数据库时,SQL注入风险会跨越数据库边界。如果应用层把用户输入直接拼进SQL,且查询涉及联邦昵称,攻击者构造的恶意SQL会经由DB2下推到远端,影响范围就不止一个库了。虽然这属于应用层的老问题,但联邦放大了风险半径,值得单独提醒。
5.3 权限设计:给联邦用户的权限需要多细
联邦环境下的权限体系比单库环境复杂,因为涉及本地权限和远端权限两张权限表。
本地侧:用户需要有对NICKNAME的查询、引用权限。
GRANT SELECT ON NICKNAME ORA_CUSTOMERS TO APP_ROLE;远端侧:USER MAPPING里配置的远端用户,只需要有对应表的SELECT权限(或者更严格的,只给具体字段的SELECT权限)。
我在项目里通常的做法是:在远端专门创建一个只读账号,并配合只读的表权限,本地只把这一个映射给对应的应用账号。这样即使本地出现权限误配或者被拖库,远端数据也只会暴露可查询的部分,不会被篡改。
此外,对于敏感字段,还可以结合DB2的列级权限控制,在创建昵称后,只授权非敏感列给普通用户:
GRANT SELECT (CUSTOMER_ID, CUSTOMER_NAME) ON NICKNAME ORA_CUSTOMERS TO APP_ROLE;联邦场景下权限越细,安全边界越清晰,切不能图省事一把梭。
6. 联邦的版本演进与常见误解澄清
6.1 不同版本的功能差异
DB2联邦功能从DB2 8时代就有雏形,到9.5之后逐渐成熟。梳理一下关键版本差异,方便大家评估手上的环境:
| 版本 | 关键变化 |
|---|---|
| DB2 9.5 | 联邦架构完善,支持丰富数据源(Oracle、SQL Server、DB2) |
| DB2 9.7 | 支持对联邦昵称进行INSERT/UPDATE/DELETE写操作(视远端数据源能力而定) |
| DB2 10.1 | 改良联邦优化器,提升下推查询性能 |
| DB2 10.5 | 支持联邦到Hadoop(通过Hive JDBC) |
| DB2 11.1 | 性能进一步优化,支持更多数据类型 |
| DB2 11.5 | 支持容器化部署,联邦功能持续演进 |
选择哪个版本没有标准答案,但如果联邦的“远端”类型很多、查询很复杂,建议至少DB2 10.5以上,优化器对下推的决策质量会明显好一些。
6.2 常见误解之一:联邦能替代分布式数据库
经常有人问:“数据库有点扛不住了,要不要开联邦做分布式?”我的回答通常很直接:联邦不是分布式数据库,它的设计目标也不是解决大规模存储或高并发写的问题。
联邦解决的是数据整合问题,数据还在原库,联邦层不存数据;而分布式数据库(如TiDB、CockroachDB、云原生数据库)是把数据分片存储到多个节点,共同构成一个逻辑库,解决的是容量和并发的问题。二者从目标到架构都不同,不能互换。
如果业务场景是“一张订单表数据量太大需要分片、需要扩节点加容量”,那应该考虑分库分表中间件或分布式数据库,联邦帮不上忙。如果场景是“要联合查询分布在多个异构数据库里的数据,又不希望搬数据”,那联邦才是合适的工具。
6.3 常见误解之二:联邦和ETL是一回事
联邦是“按需实时查询”,ETL是“预先把数据搬过来”。没有好坏之分,只有适配场景的问题。
实时性要求高、数据量适中、跨源关联列有索引支撑的场景,联邦更合适。需要做复杂的数据清洗、历史快照、长期归档的场景,ETL落到数据仓库里更靠谱。
还有一种混合做法:联邦+物化查询表(MQT)。在DB2里,可以基于联邦昵称创建MQT,用refresh table的方式定期把联邦数据物化到本地,这样既保留联邦的透明访问方式,又获得本地表的查询性能,适合“实时性要求不高、但查询很频繁”的场景。
CREATE TABLE LOCAL_CUSTOMER_SNAP AS (SELECT * FROM ORA_CUSTOMERS) DATA INITIALLY DEFERRED REFRESH DEFERRED; REFRESH TABLE LOCAL_CUSTOMER_SNAP;这种模式可以在联邦和ETL之间找一个平衡点,实际项目里我经常推荐给业务方。
6.4 顺带回应一下“Nacos支持DB2吗”这类搜索
最近在社区里看到不少人搜索“Nacos支持DB2吗”“联邦学习和联邦数据库是不是一回事”这类问题,这里一并澄清。
Nacos是注册中心和配置中心,它管理的是微服务实例的注册发现和配置下发,不是一个数据库访问中间件。Nacos本身支持外部数据库存储配置数据(MySQL是常用的),社区版本对DB2的原生支持并不好,如果非要用DB2存Nacos的配置,通常要改底层适配。但这跟DB2联邦没有任何关系,属于两个层面的东西。
“联邦学习”也和DB2联邦没有关系。联邦学习是一种分布式机器学习训练框架,多个参与方在数据不出本地的前提下联合训练模型。它解决的是数据隐私和模型协作的问题,和数据库联邦只在“联邦”这个词上撞了车,底子完全不同。DB2联邦解决的是数据库层面的跨源查询,联邦学习解决的是模型训练的数据流通问题,两码事。
搞清楚这些概念边界,面试、方案评审时就不容易被“联邦”这个词绕晕,跟业务方沟通时也能先把预期的颗粒度对齐。
7. 实战排查清单:联邦配置了但查询报错,从哪入手
最后放一份我实际干活时惯用的排查清单。联邦出了问题,报错信息往往不会直接告诉你错在哪个环节,最快的路径是按以下顺序逐层排查:
| 序号 | 现象 | 排查方向 |
|---|---|---|
| 1 | 创建Wrapper报错 | 检查远程客户端库是否安装、LD_LIBRARY_PATH是否配置、FEDERATED参数是否开启、Wrapper名称是否冲突 |
| 2 | 创建Server报错 | 检查远端主机端口是否通、DBNAME是否正确、Wrapper类型是否对应 |
| 3 | 创建User Mapping报错 | 检查本地用户名是否存在、远端密码是否错误、映射是否重复 |
| 4 | 创建Nickname报错 | 检查远端Schema名是否写错、远端表是否存在、列类型是否不兼容 |
| 5 | 查询报“SQL30020N” | Server的NODE/PORT/DBNAME配置错误,或远端没起来。这是联邦最常见的连接类错误 |
| 6 | 查询报“SQL1108N” | 远端表结构已变更,本地昵称元数据过期,执行REFRESH NICKNAME |
| 7 | 查询慢 | 确认谓词是否下推、统计信息是否过期、远端索引是否存在、查询是否触发全表拉取 |
| 8 | 中文乱码 | 检查远端数据库字符集、NICKNAME列长度映射,必要时在远端包视图转换后再建昵称 |
在刚配好联邦的初期,我最推荐的方式是:先用最简单的查询验证通路——SELECT COUNT(*) FROM 昵称,能跑通说明链路没问题,再逐步加WHERE条件、JOIN、聚合,逐步验证优化器的行为。一次堆一个复杂SQL,出了问题很难定位到底哪一步配置有误。
另外,生产环境上,所有的联邦配置变更(ALTER SERVER、ALTER USER MAPPING、REFRESH NICKNAME)都应该走变更流程,因为这个链路涉及多个数据库,影响面比单库变更大得多。改一处SERVER配置,可能影响几十个昵称的查询。别问我怎么知道的——在非生产环境踩过的坑多了,自然就长记性了。
DB2联邦是个“懂行的人觉得香,不懂的人容易翻车”的功能。它不复杂,核心概念翻来覆去就那四个对象;但用得好不好,全看你对“下推”的理解和对远端库的把握。把这篇文章里的东西消化掉,再从自己的环境动手搭一套,比看一百遍文档都管用。