2016-08-17 15 views
2

私はDB2データソースとOracle 12cターゲットを持っています。 Oracleには、一般に動作している定義済みのDB2へのDBリンクがあります。Oracle DBリンク - where句の評価

私は行の変更のためにタイムスタンプ列(ROW_CHANGEDと呼ぶことができます)を持つDB2に巨大なテーブルを持っています。私は特定の時間の後に変更された行を取得したい。 DB2に

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

実行

は約後の正確に1行を返します90秒です。

今私は、DBリンク経由のOracleから同じクエリを試してみてください。

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

これは時間に実行し、タイムアウトで終わります。 いくつかのOracleドキュメントを読んで、分散クエリ最適化のヒントを見つけましたが、そのほとんどは私の場合ではないリモートテーブルにローカルで参加することを指しています。

私は絶望的に、DRIVING_SITEヒントを試してみましたが、効果はありません。

ここで、クエリのWHERE部分が評​​価されるのはどうですか?私はクエリでDB2構文ではなくOracle構文を使用する必要があるので、Oracleは最初にフルテーブルをコピーしてからwhere句を適用する可能性がありますか?私はいくつかの研究をしましたが、この方向で私を助けるものは何も見つかりませんでした。

ROW_CHANGEDは、DB2の隠しカラムです(重要な場合)。

任意のヒントのThxを事前に指定します。助けのためのすべての@

更新

感謝。私は何を私のためのトリックを共有するでしょう。

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

説明書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

違いは、あなたの2つのクエリの違いは、TO_TIMESTAMP()です。 DBリンクに精通していませんが、なぜこれが必要なのか分かりません。 –

+0

私はテストするDB2インスタンスを持っていませんが、データ型が異なっているようで、DB2データやフル・テーブル・スキャンを暗黙的に変換する可能性があります。代わりに 'TO_DATE( '2016-08-01 10:00:00'、 'YYYY-MM-DD HH24:MI:SS')'を使用するのが助けになりますか? –

+1

リンクバージョンの実行計画を追加すると便利な場合があります。特に述語情報を使用して、DB2表の列に対して関数を呼び出すかどうかを調べます。 –

答えて

1

to_timestampのようなOracle固有の変換関数を実際に使用している場合、Oracle側で述部を評価する必要があります。オラクルは、to_timestampのような組み込み関数をDB2のまったく同等の関数呼び出しに変換する方法を知りません。

バインド変数を使用した場合、DB2側で評価される可能性が高くなります。しかし、それは異なるデータベース間のデータ型マッピングによって複雑になる可能性があります。あるエンジンのdateと別のエンジンのtimestampデータ型の間に完全なマッピングがない場合があります。これが数値列の場合、バインド変数はほとんど確実にプッシュされます。この場合、フレームワーク、Oracle、およびDB2で動作する変数に使用するデータ型を正確に把握するために、多少の演奏が必要になるでしょう。

バインド変数を使用しても機能しない場合は、dbms_hs_passthrough packageを使用してリモートサーバーで述部を評価するように強制できます。これにより、DB2サーバーに定義されている関数を使用できるようにするリモート・サーバーに問合せをそのまま伝えることができます。このような状況ではごくわずかですが、うまくいけば簡単ですが、単純なソリューションが十分に速く動作しない場合は、バックアップとしてハンマーを使用するのが良いことです。

+0

これは正しい軌道に乗るので、答えとしてマークします。バインド変数が動作すると思われますが、コネクタの設定(私の場合はODBC)で適応が必要な場合があります –