2016-08-17 59 views
2

我有一个DB2数据源和一个Oracle 12c目标。 Oracle有一个指向正在工作的DB2的DB链接。Oracle DB链接 - where子句评估

现在我在DB2中有一个巨大的表,其中有一个用于更改行的时间戳列(让我们称之为ROW_CHANGED)。我想要检索在特定时间后更改的行。

上的DB2运行

SELECT * FROM lib.tbl WHERE ROW_CHANGED >'2016-08-01 10:00:00'

约1小时后正好返回1行90秒,这很好。

现在,我尝试从Oracle相同的查询通过数据库链接:

SELECT * FROM [email protected]_name WHERE ROW_CHANGED >TO_TIMESTAMP('2016-08-01 10:00:00')

这会运行小时,超时结束。 我阅读了一些Oracle文档,发现了分布式查询优化技巧,但其中大多数提到将本地连接到远程表,这不是我的情况。

在我的绝望中,我尝试过DRIVING_SITE提示,但没有效果。

现在我想知道WHERE部分的查询将被评估。由于我必须使用Oracle语法而不是查询的DB2语法,是否有可能Oracle会尝试先复制整个表并在之后应用where子句?我做了一些研究,但没有找到任何有助于我朝这个方向发展的事情。

ROW_CHANGED是DB2中的一个隐藏列,如果这很重要的话。

Thx任何提示提前。

更新

感谢@所有的帮助。我会分享一下我的诀窍。

首先,我使用了TO_TIMESTAMP,因为DB2列也是Timestamp(不是日期),而且我期望通过这个来避开隐式转换。 没有明确的转换,我碰到了ORA-28534: Heterogeneous Services preprocessing error,我没有希望在合理的时间内触摸数据库配置。

解释计划btw并没有带来太多。它显示了一个完整的提示,并且没有对谓词进行转换。事实上,它显示ROW_CHANGED列为Date,我不知道为什么。

我试过贾斯汀建议使用绑定变量,但是我又得到了ORA-28534。接下来我做的是将它包装到一个pl/sql块(稍后将在SP中运行)。

declare 
v_tmstmp TIMESTAMP := 01.08.16 10:00:00; 
begin 

INSERT INTO ORAUSER.TMP_TBL (SRC_PK,ROW_CHANGED) 
SELECT SRC_PK,ROW_CHANGED 
FROM [email protected]_name 
WHERE ROW_CHANGED > v_tmstmp; 
end; 

这与DB2本身的执行时间相同。日期格式为DD.MM.YY,因为它是不幸的默认值。 将变量赋值更改为

v_tmstmp TIMESTAMP := TO_TIMESTAMP('01.08.16 10:00:00','DD.MM.YY HH24:MI:SS'); 

我得到了和以前一样的问题。

与此同时,DB2操作员在当天早些时候请求的ROW_CHANGED列中创建了一个索引。这似乎解决了一般问题。即使我原来的查询现在也很快完成。

+0

这两个查询之间唯一的区别似乎很可能是:TO_TIMESTAMP()函数。不熟悉数据库链接,但我不明白你为什么需要这个? – 2016-08-17 14:49:33

+0

我没有要测试的DB2实例,但看起来数据类型不同,可能导致DB2数据和/或全表扫描的隐式转换。是否使用'TO_DATE('2016-08-01 10:00:00','YYYY-MM-DD HH24:MI:SS')'而不是帮助? –

+1

添加链接版本的执行计划可能很有用;特别是谓词信息,以查看它是否正在调用针对DB2表列的函数。 –

回答

1

如果您实际使用特定于Oracle的转换函数(如to_timestamp),则会强制在Oracle端评估谓词。 Oracle不会知道如何将诸如to_timestamp之类的内置函数转换为DB2中完全等效的函数调用。

如果您使用了一个绑定变量,那么在DB2端更有可能进行评估。但是,这可能因不同数据库之间的数据类型映射而变得复杂 - 在一个引擎的date与另一个引擎的timestamp数据类型之间可能没有完美的映射。如果这是一个数字列,绑定变量几乎肯定会被推送。在这种情况下,可能需要花费一点时间才能找出适用于您的框架,Oracle和DB2的变量的确切数据类型。

如果使用绑定变量不起作用,则可以使用dbms_hs_passthrough package强制在远程服务器上评估谓词。这使您可以逐字地向远程服务器发送查询,从而允许您执行DB2数据库中定义的使用函数等功能。希望这种情况有点矫枉过正,但如果简单的解决方案不能很快地工作,那么将锤子作为备份是很好的。

+0

这让我走上了正轨,所以我将它标记为答案。似乎绑定变量将工作,但可能需要在连接器配置中调整(在我的情况下,ODBC) –