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 列にインデックスを作成しました。これにより、一般的に問題が解決したようです。私の元のクエリでさえ、すぐに終了します。