Oracle DB链接 - where子句评估

时间:2016-08-17 14:17:05

标签: db2 oracle12c database-link

我有一个DB2数据源和一个Oracle 12c目标。 Oracle具有指向DB2的数据库链接,该链接通常正在运行。

现在我在DB2中有一个巨大的表,它有一个时间戳列(让我们称之为ROW_CHANGED)来进行行更改。我想检索在特定时间后发生变化的行。

运行

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

DB2上的

正好在ca后返回1行。 90秒这很好。

现在我通过db链接从Oracle尝试相同的查询:

SELECT * FROM lib.tbl@dblink_name WHERE ROW_CHANGED >TO_TIMESTAMP('2016-08-01 10:00:00')

这会持续数小时,最后会超时。 我阅读了一些Oracle文档,发现了分布式查询优化提示,但大多数提示将本地连接到远程表,这不是我的情况。

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

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

如果重要的话,ROW_CHANGED是DB2中的隐藏列。

预先提示任何提示。

更新

谢谢@大家帮忙。我会分享给我的诀窍。

首先,我使用了TO_TIMESTAMP,因为DB2列也是时间戳(不是日期),我原本希望通过这种方式绕过隐式转换。 如果没有显式转换,我会遇到ORA-28534: Heterogeneous Services preprocessing error而我无法在合理的时间内触及数据库配置。

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

我已经尝试过Justins建议使用绑定变量,但是我再次获得了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 lib.tbl@dblink_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列中创建了一个索引。这似乎解决了一般问题。甚至我的原始查询现在也很快就完成了。

1 个答案:

答案 0 :(得分:1)

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

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

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