Какие ресурсы используются в локальной базе данных Oracle при выполнении запроса к связанной базе данных?

#oracle #performance #hyperlink #resources

Вопрос:

Я пишу приложение на C#, которое будет выполнять запросы к локальной и связанной базам данных (все Oracle 10g и новее), и я хочу убедиться, что понимаю, кто что делает, когда запрашивается связанная база данных.

Например, для простого запроса, такого как

SELECT * FROM FOO@DB_LINK

За что отвечает локальный сервер базы данных? Я предполагаю, что при этом будут использоваться процессор, диск и память на сервере баз данных , на котором размещен DB_LINK , но какое влияние этот запрос оказывает на ресурсы локального сервера баз данных?

Что делать, если запрос немного сложнее, например

SELECT * FROM FOO@DB_LINK F INNER JOIN BAR@DB_LINK B ON F.FOOBAR = B.FOOBAR

Выполняется ли весь запрос на сервере , на котором он размещен DB_LINK , или INNER JOIN выполняется на локальном сервере? Если INNER JOIN это выполняется локальной базой данных, может ли она использовать индексы, которые находятся в связанных таблицах (я бы так не подумал)? Есть ли способ сообщить Oracle о выполнении всего запроса в связанной базе данных?

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

SELECT * FROM FOO F INNER JOIN BAR@DB_LINK B ON F.FOOBAR = B.FOOBAR

Подводя итог,

  1. Я имею дело только с базами данных Oracle 10g или новее.
  2. За что отвечает локальный сервер базы данных, когда запрос (каким бы сложным он ни был) выполняется строго в отношении связанных таблиц?
  3. Каковы способы (если таковые имеются) оптимизации или предоставления подсказок Oracle о том, как наилучшим образом выполнять такого рода запросы? (примеры на C# были бы великолепны)

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

1. Руководство администратора базы данных Oracle немного рассказывает об этом в Главе 32.4 Настройка распределенных запросов

2. Спасибо @kfinity, однако объем документации таков: «Локальный сервер баз данных Oracle разбивает распределенный запрос на соответствующее количество удаленных запросов, которые затем отправляет удаленным узлам для выполнения. Удаленные узлы выполняют запросы и отправляют результаты обратно на локальный узел. Затем локальный узел выполняет любую необходимую последующую обработку и возвращает результаты пользователю или приложению». Как Oracle определяет, где разбить распределенный запрос на удаленные запросы? Достаточно ли умен, чтобы определить, что запрос ко всем удаленным объектам может быть передан полностью?

Ответ №1:

Как и большинство вещей, связанных с оптимизатором, это зависит от обстоятельств.

Если вы создадите план запроса для конкретного запроса, план запроса сообщит вам, что делает локальная база данных и какие операции выполняются в удаленной базе данных, если что-то выполняется. Скорее всего, если статистика по объектам достаточно точна и запрос ссылается только на объекты в одной удаленной базе данных, оптимизатор будет достаточно умен, чтобы отправить весь запрос на удаленный сервер для выполнения.

Увы, оптимизатор не всегда будет достаточно умен, чтобы поступать правильно. Если это произойдет, вы, скорее всего, сможете решить эту проблему, добавив соответствующую driving_site подсказку в запрос.

 SELECT /*  driving_site(F) */ * 
  FROM FOO@DB_LINK F 
       INNER JOIN BAR@DB_LINK B 
          ON F.FOOBAR = B.FOOBAR
 

В зависимости от того, насколько сложны запросы, насколько сложно добавлять подсказки к вашим запросам и насколько сложно в вашей среде заставить работать оптимизатор, создание представлений в удаленной базе данных может быть еще одним способом принудительного выполнения запросов в удаленной базе данных. Если вы создадите представление на db_link это объединяет две таблицы вместе и запрашивает просмотр по ссылке на базу данных, что (по моему опыту) всегда заставляет выполнение выполняться в удаленной базе данных, в которой определено представление. Я бы не ожидал, что эта опция понадобится, учитывая тот факт, что вы не смешиваете локальные и удаленные объекты, но я включаю ее для полноты.

Ответ №2:

Удаленный запрос на 100% будет оптимизирован удаленным экземпляром. Локальному экземпляру все равно потребуется выделить немного памяти и использовать процессор для получения результатов с удаленного сервера, но основная работа (такие вещи, как хэш-соединения и циклическое выполнение) будет выполняться удаленным экземпляром.

Когда это произойдет, вы получите заметку в своем локальном плане выполнения

 Note
-----
   - fully remote statement
 

Как только что-то требуется сделать на локальном сервере (например, вставка или если вы присоединяетесь к локальной таблице (включая локальную двойную)) как часть инструкции, запрос становится распределенным, только один сервер может считаться ведущим сайтом, и обычно он будет локальным (я не могу придумать демонстрацию, в которой выбирается удаленный сайт, даже если он дешевле, поэтому, возможно, он не основан на затратах). Как правило, это приведет к тому, что вы где — то столкнетесь с какой-то проблемой-возможно, присоединением вложенного цикла к удаленным таблицам, вычисленным на локальной стороне.

При работе с распределенными запросами следует иметь в виду одну вещь — оптимизирующий экземпляр не будет просматривать информацию о гистограмме из другого экземпляра.