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

Есть только одна проблема.

Данные в MV должны быть свежими. В противном случае Oracle не будет переписывать.

Вы, конечно, можете запросить MV напрямую. Но данные все равно будут старыми.

Поэтому вам нужно постоянно обновлять материализованное представление. Самый простой способ - объявить это как «быстрое обновление при фиксации».

Но легче сказать, чем сделать. При этом возникает пара проблем:

Поэтому, если у вас сложный SQL, возможно, вы не сможете использовать перезапись запроса. И даже если вы можете, в системах с большим количеством транзакций накладные расходы на обновление могут вывести вашу систему из строя.

Таким образом, вместо «быстрого обновления при фиксации» вы делаете MV «быстрое обновление по запросу». И создайте задание по его обновлению. Которая проходит каждую секунду!

Но независимо от того, как часто вы запускаете задание, всегда будут моменты, когда MV устареет. Таким образом, производительность запроса может переключаться между молниеносной скоростью и медленной как собака. Гарантированный способ расстроить ваших пользователей!

Так как же это преодолеть?

С материализованными представлениями в реальном времени!

Они дают лучшее из обоих миров. Вы можете обновить свой клип по запросу. Но все же он должен возвращать актуальную информацию.

Для этого создайте MV с предложением:

при вычислении запроса

Например:

create table t (
  x not null primary key, y not null
) as 
  select rownum x, mod(rownum, 10) y 
  from   dual connect by level <= 1000; 
create materialized view log on t 
  with rowid (x, y) including new values; 
create materialized view mv 
refresh fast on demand 
enable on query computation 
enable query rewrite as 
  select y , count(*) c1 
  from   t 
  group by y;

С его помощью вы можете добавить больше данных в свою таблицу:

insert into t 
  select 1000+rownum, 1 from dual 
  connect by level <= 100; 
commit;

И Oracle все еще может использовать MV для переписывания. Даже если клип устарел!

select /*+ rewrite */y , count(*) from t group by y;

Это достигается за счет:

  • Запрос устаревшего MV
  • Затем применяя к нему вставки, обновления и удаления в журнале MV.

Это может привести к появлению устрашающих планов выполнения!

Следует помнить, что Oracle читает журнал материализованного представления. Затем применяем изменения к MV. Таким образом, чем дольше вы оставите его между обновлениями, тем больше будет данных. Вам нужно будет протестировать, чтобы найти золотую середину для балансировки процесса обновления и применения журналов изменений MV при перезаписи запроса.

Вы даже можете получить самую свежую информацию, напрямую запросив MV. Для этого добавьте подсказку fresh_mv:

select /*+ fresh_mv */* from mv;

Действительно крутая часть?

Вы можете преобразовать существующие видео в реальном времени с помощью следующей команды:

alter materialized view mv enable on query computation;

Это значительно упрощает работу с MV, открывая возможности настройки запросов!

Полная статья изначально опубликована на сайте blogs.oracle.com 10 ноября 2016 г.