Создание материализованного представления выполняется быстро, но обновление в Oracle 19c занимает несколько часов

#oracle #materialized-views #mv #materialized

Вопрос:

Недавно мне нужно создать несколько материализованных представлений на Oracle 19c, все базовые таблицы расположены в удаленной базе данных oracle, запрос использует dblink для подключения таблиц, и быстрое обновление не допускается. Большинство из них могут завершить обновление за считанные секунды после добавления некоторых подсказок, таких как use_hash и т. Д. Но при создании одного с объединением в запросе подсказки вообще не работают, к счастью, есть только одно объединение, поэтому я разделил запрос на две части, но возникает другая проблема: создание одного из материализованных представлений занимает не более 10 секунд, но требуется несколько часов, даже дни не могут завершить обновление. Я поискал в Интернете и получил ответы ниже:

  1. используйте dbms_mview.refresh(mv_name, ‘C’, atomic_refresh=>false). Это решение не работает.
  2. быстрое обновление. Решение не допускается.
  3. Вместо того, чтобы обновлять, каждый раз заново создавайте материализованное представление, это обходной путь, но не решение.
  4. Используйте подсказку optimizer_features_enable(9.0.0), я смоделировал проблему в таблице (так как я не могу вставить в…select… на материализованном представлении), кажется, подсказка работает, но когда я попытался применить подсказку к материализованному представлению, из плана выполнения я вижу, что подсказка была проигнорирована. Я также попытался добавить alter session set optimizer_features_enable=’9.0.0′ в задание планировщика перед dbms_refresh.refresh(mv_name), но это не работает. Хотел бы знать, есть ли у кого-нибудь какие-либо идеи по этой проблеме? Спасибо.

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

1. Материализованные представления используют ваш SQL (с подсказками) только в момент их создания. При обновлении Oracle автоматически генерирует свой собственный SQL, и он может не соответствовать вашему оригиналу во всех отношениях (предикаты могут изменить порядок, подсказки исчезнут и т.д.), Поскольку Oracle пытается оптимизировать себя. Это внутренняя операция, и ее нельзя контролировать; Oracle всегда будет генерировать свой собственный SQL для обновления. Все, что вы можете сделать, — это косвенно оптимизировать производительность с помощью таких вещей, как текущая статистика таблиц, соответствующие индексы и конфигурация памяти.

2. Вы также можете попробовать создать представление с нужными подсказками и основать материализованное представление на промежуточном представлении.

3. Спасибо @pmdba! Не ожидал получить ответ так скоро. Спасибо за разъяснение. Ваше предложение-хороший обходной путь, давайте посмотрим, будут ли какие-либо другие предложения. Нужно некоторое время и доказательства, чтобы убедить команду остановиться здесь…

Ответ №1:

Джонатан из сообщества oracle только что дал мне решение для моего конкретного запроса. Поскольку все поля моего запроса поступают из удаленной базы данных, за исключением функции systimestamp, поэтому я могу отделить функцию от внешнего оператора select и сделать все удаленные поля в качестве оператора sub-select, а затем добавить к нему подсказку no_merge, это заставит включиться оптимизатор удаленной базы данных.

 SELECT systimestamp, v.*
  FROM (
    my original query with /*  no_merge */
) v;