2016-08-17 3 views
2

У меня есть источник данных DB2 и цель Oracle 12c. Oracle имеет ссылку DB для DB2, которая работает в целом.Oracle DB link - где оценка предложения

Теперь у меня есть огромная таблица в DB2, которая имеет столбец timestamp (позволяет называть ROW_CHANGED) для изменения строк. Я хочу получить строки, которые изменились после определенного времени.

Запуск

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

на DB2 возвращает ровно 1 строку после ок 90 секунд, что хорошо.

Теперь я попробовать тот же запрос с Oracle по ссылке БД:

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

Это работает в течение нескольких часов и заканчивается в тайм-аут. Я прочитал некоторые документы Oracle и нашел советы по оптимизации распределенных запросов, но большинство из них ссылаются на присоединение локального к удаленной таблице, что не мое дело.

В отчаянии я пробовал подсказку DRIVING_SITE, без эффекта.

Теперь мне интересно, когда будет обрабатываться часть WHERE. Поскольку я должен использовать синтаксис Oracle, а не синтаксис DB2 для запроса, возможно ли, что Oracle попытается сначала скопировать всю таблицу и применить предложение where впоследствии? Я провел некоторое исследование, но не нашел ничего, что могло бы помочь мне в этом направлении.

ROW_CHANGED - скрытый столбец в DB2, если это имеет значение.

Thx для любого намека.

Update

Спасибо @ все за помощь. Я поделюсь тем, что сделал трюк для меня.

Прежде всего, я использовал 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

Кажется вероятным, что разница будет единственной разницей между вашими двумя запросами: функцией TO_TIMESTAMP(). Не знакомы с ссылкой БД, но я не понимаю, зачем это нужно? –

+0

У меня нет экземпляра DB2 для тестирования, но похоже, что тип данных отличается и, возможно, вызывает неявное преобразование данных DB2 и/или полное сканирование таблицы. Использует ли 'TO_DATE ('2016-08-01 10:00:00', 'YYYY-MM-DD HH24: MI: SS')' вместо этого помогает? –

+1

Возможно, было бы полезно добавить план выполнения для версии ссылки; в частности информацию предиката, чтобы узнать, вызывает ли она функцию против столбца таблицы DB2. –

ответ

1

Если вы действительно используете функцию преобразования, специфичную для Oracle, такую ​​как to_timestamp, это заставляет предикат оцениваться на стороне Oracle. Oracle не будет знать, как преобразовать встроенную функцию, например to_timestamp, в эквивалентный вызов функции в DB2.

Если вы использовали переменную связывания, более вероятно, что ее можно будет оценить на стороне DB2. Но это может быть осложнено сопоставлением типов данных между различными базами данных - может быть не идеальное сопоставление между date и другим типом данных двигателя timestamp. Если бы это был числовой столбец, переменная связывания почти наверняка была бы нажата. В этом случае, вероятно, требуется немного поразвлечься, чтобы точно определить, какой тип данных использовать для вашей переменной, которая работает для вашей инфраструктуры, Oracle и DB2.

Если переменная привязки не работает, вы можете принудительно оценить предикат на удаленном сервере с помощью dbms_hs_passthrough package. Это позволяет отправлять запрос дословно на удаленный сервер, который позволяет вам выполнять такие функции, как функции использования, определенные в вашей базе данных DB2. Надеюсь, в этой ситуации это чересчур избыточно, но приятно иметь молоток в качестве резервной копии, если более простое решение не работает достаточно быстро.

+0

Это поставило меня на правильный путь, поэтому я отмечаю его как ответ. Кажется, переменная связывания будет работать, но может потребоваться адаптация в конфигурации коннектора (ODBC в моем случае) –

Смежные вопросы