Обновление материализованного представления при изменении таблиц
У меня есть материализованное представление, определенное так:
CREATE MATERIALIZED VIEW M_FOO
REFRESH COMPLETE ON COMMIT
AS
SELECT FOO_ID, BAR
FROM FOO
WHERE BAR IS NOT NULL
GROUP BY FOO_ID, BAR
/
COMMENT ON MATERIALIZED VIEW M_FOO IS 'Foo-Bar pairs';
Я написал что-то вроде кеша: исходная таблица огромна, но количество разных пар довольно мало. Мне нужны эти пары, чтобы соединить их с другими таблицами. Пока все хорошо: это абсолютно ускоряет запросы.
Но я хочу убедиться, что представление не содержит устаревших данных. Базовая таблица изменяется четыре или пять раз в месяц, но я не обязательно знаю, когда. Я понимаю, что материализованное представление можно определить, чтобы оно обновлялось при изменении исходных таблиц. Однако, документы становятся довольно сложными.
Какой точный синтаксис мне нужно использовать?
Нужно ли создавать материализованный журнал просмотра?
В чем разница между быстрым и полным обновлением?
2 ответа
Чтобы ответить на ваши вопросы в обратном порядке
Быстрое обновление также называется инкрементным обновлением. Это должно дать вам ключ к разнице. Обновление COMPLETE восстанавливает весь MVIEW с нуля, тогда как обновление FAST применяет только те изменения из DML, которые были рассчитаны для таблиц фидеров.
Для выполнения обновлений FAST вам необходим соответствующий журнал MVIEW.
Что касается синтаксиса, хорошо вот основы:
SQL> create materialized view log on emp
2 with rowid, primary key, sequence (deptno, job)
3 including new values
4 /
Materialized view log created.
SQL> create materialized view emp_mv
2 refresh fast on commit
3 as
4 select deptno, job from emp
5 group by deptno, job
6 /
Materialized view created.
SQL>
ON COMMIT
предложение означает, что MVIEW обновляется транзакционно (в отличие от ON DEMAND
который регулярно обновляется навалом). REFRESH
в пунктах указывается, применять ли инкрементные или полные обновления. Есть несколько категорий запросов, которые заставляют использовать COMPLETE
обновить, хотя они, похоже, уменьшаются с каждой новой версией Oracle.
Быстрый тест, чтобы увидеть, что это работает...
SQL> select * from emp_mv
2 order by deptno, job
3 /
DEPTNO JOB
---------- ---------
10 MANAGER
10 PRESIDENT
10 SALES
20 ANALYST
20 CLERK
20 MANAGER
30 CLERK
30 MANAGER
30 SALESMAN
40 CLERK
40 DOGSBODY
11 rows selected.
SQL>
Как насчет новой записи?
SQL> insert into emp (empno, ename, deptno, job)
2 values (6666, 'GADGET', 40, 'INSPECTOR')
3 /
1 row created.
SQL> commit
2 /
Commit complete.
SQL> select * from emp_mv
2 order by deptno, job
3 /
DEPTNO JOB
---------- ---------
10 MANAGER
10 PRESIDENT
10 SALES
20 ANALYST
20 CLERK
20 MANAGER
30 CLERK
30 MANAGER
30 SALESMAN
40 CLERK
40 DOGSBODY
40 INSPECTOR
12 rows selected.
SQL>
Вы можете найти более подробную информацию о синтаксисе в справочнике по SQL. Также стоит прочитать главу " Материализованное представление" в Руководстве по хранилищу данных.
Быстрое обновление только вставит / обновит / удалит измененные данные в материализованное представление. Полное обновление очистит материализованное представление, а затем скопирует все строки.
"При фиксации" означает, что материализованное представление будет обновляться всякий раз, когда в основной таблице фиксируется изменение. Таким образом, ваш текущий синтаксис будет крайне неэффективным. Каждый раз, когда кто-либо изменяет какую-либо строку в foo, m_foo будет обрезаться, а затем будет вставляться каждая строка в таблице foo.
Вы можете добиться большего успеха с помощью быстрого обновления, когда только измененные строки в foo будут отправлены в m_foo. Это дает вам последовательность без больших накладных расходов.
создать материализованный вид журнала на foo с первичным ключом; - при условии, что у вас есть первичный ключ, вы должны создать материализованное представление m_foo для быстрого обновления при фиксации как \;
Есть некоторые дополнительные тонкости с грантами и синонимами, если вы используете ссылки db, или схема, которой принадлежит foo, не та, которая владеет m_foo.