Как оптимизировать сложный распределенный запрос?

#sql #database #oracle #cursor #remote-server

#sql #База данных #Oracle #курсор #удаленный сервер

Вопрос:

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

Я дам некоторую информацию для анализа,

  • В запросе нет локальных таблиц, только ссылки на удаленную базу данных.
  • Запрос Cursor использует 6 удаленных ссылок на БД и выполняет операции объединения над ними.
  • Все ссылки на базы данных указывают на одну и ту же базу данных, но на разные таблицы.
  • SELECT не имеет никаких агрегированных операций и имеет только функции NVL для нескольких столбцов
  • Выбирается примерно 90 столбцов

Структура запроса является

 SELECT (SOME 90 COLUMNS)
FROM    master1_all@db_one m1,
        master2_all@db_one m2,
        prey1@db_one pa,
        prey2@db_one pb,
        prey2@db_one pc,
        tbl_abc@db_one xa,
    (SELECT
      geo.country,
      geo.state
    FROM  tb_dest@db_one geo ) geo  WHERE ( m1.master_key = m2.master_key ) AND
    ( pc.weather_key = m2.cloud_key ) AND
( m1.order_type_id = pa.weather_key ) AND
( pa.weather_key = pb.weather_key ) AND
( m2.food_store_key = xa.food_store_key ) AND
( (nvl(m2.shop_key ,121)) = xa.store_key ) AND
( geo.country ( ) = m1.country ) AND
(xa.food_type NOT IN ('COLD')) AND
( m2.food_type_code NOT IN ('WINTER')
    OR m2.price_per_portion !=0 ) AND
( ( m1.last_purchase_date >= TRUNC(SYSDATE-10) - 1/48 And m1.last_purchase_date <= TRUNC(SYSDATE) ) 
Or ( m2.last_purchase_date >= TRUNC(SYSDATE-10) - 1/48 And m2.last_purchase_date <= TRUNC(SYSDATE) ));
  

Это не фактический запрос, но структура похожа.

Комментарии:

1. Пожалуйста, опубликуйте запрос!

2. Зачем вам 4 отдельные ссылки на базу данных, которые все подключаются к одной базе данных? Вы имеете в виду, что у вас есть 4 удаленных объекта, на каждый из которых ссылается одна ссылка на базу данных? Можете ли вы подключиться к удаленным системам? Есть ли надежда на репликацию данных в вашей локальной системе перед их обработкой

3. @JustinCave Извините. Произошла ошибка… все шесть подключаются к одной базе данных. Сейчас я отредактирую вопрос.

4. Попробуйте использовать синтаксис ANSI join, он более удобочитаемый и менее подвержен ошибкам. И почему вы используете так много бесполезных скобок?

5. @Boneist Да. Я бы сделал это, но у меня нет доступа.

Ответ №1:

Прежде всего попытайтесь найти бутылочное горлышко вашего запроса. Если проблема только с выполнением запроса из удаленной таблицы, вы можете использовать подсказку /* DRIVING_SITE(…) */ https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements006.htm#BABEGIJC И oracle попытается выполнить в базе данных remoute

Комментарии:

1. Использование подсказок — это хорошо, но все таблицы взяты из удаленных ссылок на базу данных.

2. Вот почему я говорю о DRIVING SITE том, что если вы используете эту подсказку, oracle попытается выполнить запрос (выполнить объединения, сортировки и т.д.) В удаленной базе данных и вернет вам только результат. Обычно это быстрее, чем получать любые данные из удаленной базы данных и выполнять запрос на текущем сайте

3. хорошо. то есть вы хотите сказать, что я могу дать подсказку типа /* DRIVING_SITE(m1, m2, pa, pb, pc, xa) * / не так ли?

4. Насколько я знаю, этого достаточно указать только один псевдоним /* DRIVING_SITE(m1) */ .

5. Может быть, это означает, что выполнение запроса занимает не так много времени, но извлечение всего набора обходится дорого, или какие-либо другие причины, по которым это может работать не так хорошо