Низкая производительность Вставьте оператор, когда представление выбора содержит dblink - PullRequest
0 голосов
/ 11 октября 2018

У меня проблемы с оператором Insert в oracle 12.2.У меня есть запрос, как это:

INSERT INTO LOCAL.TABLE_1 ( column1, column2....) 
SELECT  column1, column2
FROM (BLOCK CODE WITH SELECT AND INNER JOIN)
(
INNER JOIN (SELECT columnx, columny, columnz,columna, columnb...
FROM (SELECT columnx, columny, columnz FROM LOCAL.ViewA WHERE....) S
INNER JOIN (SELECT columna, columnb FROM LOCAL.ViewB WHERE....)D 
ON ..... )
)A WHERE b = 1;

И запрос ViewA и B, как это:

Select columnA, columnB, columnC FROM REMOTE.CUSTOMERS@DBLCUSTOMER;

Проблемы:

  • Намек нетработать для оператора вставки, как APPEND, Driving_Site, Parallel даже Nologing.Вставка 2 миллионов записей из удаленной в локальную таблицу заняла почти 2 часа.Я попытался отладить, оператор выбора просто займет 8 секунд, чтобы получить 2 миллиона записей из удаленной таблицы.
  • Может ли какая-либо подсказка работать для ViewA и ViewB?Это очень плохая производительность, когда я использую подсказку, такую ​​как Driving_Site (Это хорошая производительность, если я не использую).Я не могу использовать dblink вместо View для блочного кода из-за правила компании.

Есть ли какое-либо решение, улучшающее производительность в этом случае?

1 Ответ

0 голосов
/ 11 октября 2018

мой комментарий для вас слишком длинный для комментария, так что здесь у вас есть его в качестве ответа, даже если это не ответ типа «вот ваше исправление».У меня есть две идеи для вас.HTH

  1. Может быть, когда вы говорите, что SELECT занимает всего 2 секунды, вы выбираете не все строки, а только первые 50?Если вы используете Oracle SQL Developer, вы можете щелкнуть набор результатов, а затем нажать Ctrl + A, чтобы узнать, сколько времени занимает выборка всех строк.
  2. О том, что ваши подсказки не работают и выбор занимает больше времени, когда он является частьювставить, я могу предоставить эту цитату отсюда: https://jonathanlewis.wordpress.com/2008/12/05/distributed-dml/

Распределенный оператор DML должен выполняться в базе данных, где находится цель DML.Подсказка DRIVING_SITE не может переопределить это.

Таким образом, в сценарии распределенного DML oracle обрабатывает все (данные базовой таблицы перед объединениями) и выполняет объединения и т.д. локально.Но есть надежда, цитируя ту же ссылку:

Если вы хотите, чтобы этот пример присоединился удаленно, вам нужно будет создать представление объединения на удаленном сайте и запросить представление.

Вот как я это делаю.Этот пример для активной DG, где я хочу, чтобы вся рабочая нагрузка на DG и RDS выполнялась только для вставки, и только ссылки для вставки передаются по ссылке DB:

-- RDS
-- First we create the results table on the RDS
create table your_schema.your_table [...]


-- RDS (Due to DG I have to create it on RDS and it makes it's way to the DG)
-- Now we create a VIEW with your huge long running query
create view your_schema.your_view as
select  [...];  -- your huge long running query is here


-- DG
-- Now you fill the RDS Table you created. As the results come from a VIEW and the query is executed on DG, all the workload is done on DG
insert into your_schema.your_table@DBLINK_TO_RDS
select  * from your_schema.your_view;
commit;

ВПосле выполнения плана на RDS вы видите, что вся работа выполнена на DG.Вы видите только «загрузить таблицу обычных» и «удаленный».И в плане выполнения на DG вы видите все крупные объединения и прочее.

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

select 
sum(TM_DELTA_TIME), sum(TM_DELTA_CPU_TIME), sum(TM_DELTA_DB_TIME), sum(DELTA_READ_IO_REQUESTS), sum(DELTA_WRITE_IO_REQUESTS), sum(DELTA_READ_IO_BYTES),
sum(DELTA_WRITE_IO_BYTES), sum(DELTA_INTERCONNECT_IO_BYTES), max(PGA_ALLOCATED), max(TEMP_SPACE_ALLOCATED)
from gv$active_session_history where session_id = 3X5 and SESSION_SERIAL# = 2XXX0 and SAMPLE_ID > 4XXXXX6 and sample_id <= 4XXXXX9;
...