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 行後に正確に 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 部分がいつ評価されるのだろうか。クエリにDB2構文ではなくOracle構文を使用する必要があるため、Oracleが最初に完全なテーブルをコピーし、その後where句を適用しようとする可能性はありますか? 私はいくつかの調査を行いましたが、この方向に役立つものは何も見つかりませんでした.

ROW_CHANGED は、問題がある場合、DB2 の非表示の列です。

事前にヒントをお寄せください。

アップデート

@all 助けてくれてありがとう。私は何が私のためにトリックをしたかを共有します.

まず、DB2 列もタイムスタンプ (日付ではない) であるため、TO_TIMESTAMP を使用しました。これにより、暗黙的な変換を回避することが期待されていました。明示的な変換がなければ、ORA-28534: Heterogeneous Services preprocessing error妥当な時間内に DB 構成に触れることはできません。

ところで説明計画はあまりもたらしませんでした。完全なヒントが表示され、述語に変換がありませんでした。確かに、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 列にインデックスを作成しました。これにより、一般的に問題が解決したようです。私の元のクエリでさえ、すぐに終了します。

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 に答える