#oracle #materialized-views #mv #materialized
Вопрос:
Недавно мне нужно создать несколько материализованных представлений на Oracle 19c, все базовые таблицы расположены в удаленной базе данных oracle, запрос использует dblink для подключения таблиц, и быстрое обновление не допускается. Большинство из них могут завершить обновление за считанные секунды после добавления некоторых подсказок, таких как use_hash и т. Д. Но при создании одного с объединением в запросе подсказки вообще не работают, к счастью, есть только одно объединение, поэтому я разделил запрос на две части, но возникает другая проблема: создание одного из материализованных представлений занимает не более 10 секунд, но требуется несколько часов, даже дни не могут завершить обновление. Я поискал в Интернете и получил ответы ниже:
- используйте dbms_mview.refresh(mv_name, ‘C’, atomic_refresh=>false). Это решение не работает.
- быстрое обновление. Решение не допускается.
- Вместо того, чтобы обновлять, каждый раз заново создавайте материализованное представление, это обходной путь, но не решение.
- Используйте подсказку 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;