2

我有一个 DB2 数据源和一个 Oracle 12c 目标。Oracle 有一个到定义的 DB2 的 DB 链接,该链接通常工作。

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

跑步

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

在 DB2 上恰好返回 1 行之后 ca。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 中的隐藏列。

感谢您提前提供任何提示。

更新

谢谢@all 的帮助。我将分享对我有什么帮助。

首先,我使用了 TO_TIMESTAMP,因为 DB2 列也是 Timestamp(不是日期),我曾期望以此规避隐式转换。如果没有我遇到的显式转换ORA-28534: Heterogeneous Services preprocessing error,我没有希望在合理的时间内接触数据库配置。

顺便说一句,解释计划并没有带来太多。它显示了一个完整的提示,并且没有对谓词进行转换。事实上,它显示 ROW_CHANGED 列作为日期,我想知道为什么。

我已经尝试过 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 列中创建了一个索引。这似乎解决了一般问题。甚至我最初的查询现在也很快完成。

4

1 回答 1

1

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

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

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

于 2016-08-17T15:30:48.830 回答