Лимитный повтор для материализованного представления, полное обновление или ручной эквивалент


10

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

Есть ли способ сделать эту репликацию разумной в отношении генерации повторов ? MERGE, за которым следует DELETE, запрашивает источник дважды. Стоит ли массово собирать данные, чтобы выполнить BULK MERGE и DELETE? Есть ли способ лучше?

Обновить:

Я исследовал использование глобальной временной таблицы в качестве промежуточной области. Хотя они используют меньше половины повторов, они все равно используют много.


Вы можете опубликовать код gtt? GTT не генерируют повтор напрямую, но они генерируют отмену - и отмена генерирует повтор. insertops генерируют гораздо меньше откатов, чем deleteили updateops (практически ни одного). Хорошим подходом может быть наличие нескольких gtts, чтобы избежать дорогостоящих операций
Джек говорит, что попробуйте topanswers.xyz

@Jack Douglas psoug.org/reference/gtt.html имеет демонстрацию GTo Redo Generation, демонстрирующую 60% -ное уменьшение повторов между физической таблицей и GTT для inserts. Это близко соответствует результатам, которые я вижу, и лучше, но не так хорошо, как хотелось бы.
Ли Риффель

Эти тесты (построчно и без appendподсказок) не являются идеальными условиями для уменьшения повторения - я провел несколько тестов, чтобы показать, что я имею в виду. Опубликовано в качестве ответа, потому что они не вписываются в комментарий
Джек говорит попробуйте topanswers.xyz

Ответы:


5

Это просто предназначено для демонстрации повторного использования различных insertопераций, а не для ответа на весь вопрос. Результаты на моем 10g экземпляре не являются на 100% детерминированными, но общая картина оставалась неизменной каждый раз, когда я пробежал.

Для кучи таблиц я не знаю, почему insert /*+ append */генерируется больше повторов.

Testbed:

create table heap_noappend(id integer, dummy char(500));
create table heap_append(id integer, dummy char(500));
create global temporary table gtt_noappend(id integer, dummy char(500));
create global temporary table gtt_append(id integer, dummy char(500));
create global temporary table gtt_results(stage integer, val integer);

контрольная работа:

insert into gtt_results(stage, val)
select 0, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert into heap_noappend(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 1, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert /*+ append */ into heap_append(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 2, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert into gtt_noappend(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 3, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert /*+ append */ into gtt_append(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 4, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

результат:

select * 
from( select decode(stage,1,'heap noappend',
                          2,'heap append',
                          3,'gtt noappend',
                          4,'gtt append') as operation, 
             val-lag(val) over(order by stage) as redo 
      from gtt_results)
where redo is not null;

OPERATION     REDO                   
------------- ---------------------- 
heap noappend 606932                 
heap append   690768                 
gtt noappend  41488                  
gtt append    256                   

Вы правы конечно. Я должен был поймать это в своих тестах. Я попробую.
Ли Риффель

6

Хороший вопрос. Я "решил" эту проблему для моей ситуации некоторое время назад, делая MV и любые индексы на них NOLOGGING. Не было никакого смысла в моей ситуации - в любом случае я делал полное обновление представления, зачем мне повторять?


1
Вам также может понадобиться ATOMIC_REFRESH = false (для 10g и выше). Не уверены, каковы последствия для любой резервной базы данных или восстановления с архивными журналами?
Джек говорит, попробуйте topanswers.xyz

Я запускаю логический и физический резерв в базе данных, с которой я это сделал. Там нет проблем. Я столкнулся с проблемой создания копий БД - мне приходилось просматривать мои заметки, но была ошибка, которая иногда возникала при выполнении восстановления табличного пространства с таблицами записей. Я прочитал рекомендации по созданию табличного пространства, зарезервированного для таблиц / индексов, которые не являются журналами, чтобы избежать таких проблем. Я выяснил, как решить это все же.
DCookie

@ Джек, я считаю, что мне пришлось использовать не атомарное обновление.
DCookie

Хммм, если я использую стандартное материализованное представление, оно должно сделать атомное обновление, так что это не будет работать для меня. Кто-то может найти это полезным, так что это все еще хороший ответ.
Ли Риффель

Зачем нужно атомное обновление? Насколько я понимаю, установка в false только влияет на полное обновление. См. Этот пост Asktom: asktom.oracle.com/pls/apex/…
DCookie
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.