Обмежуйте повтор для повного оновлення або вручну еквівалентного подання


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 має демонстрацію покоління GTT Redo, що показує 60% зменшення повтору між фізичною таблицею та GTT для inserts. Це повністю відповідає результатам, які я бачу, і є кращими, але не настільки хорошими, як хотілося б.
Лі Ріффер

Ці тести (рядок за рядком і без appendпідказки) не є ідеальними умовами для зменшення повтору - я провів кілька тестів, щоб показати, що я маю на увазі. Опубліковано як відповідь, оскільки вони не
вмістяться

Відповіді:


5

Це покликане лише продемонструвати повторне використання різних insertоперацій, а не відповісти на все запитання. Результати на моєму екземплярі 10 г не є на 100% детермінованими, але широка картина залишалася однаковою щоразу, коли я пробігав.

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

тестова площадка:

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

Хороше питання. Я "вирішив" цю проблему для своєї ситуації ще раз, зробивши МВ та будь-які індекси на них НОЛОГІНГ. Моя ситуація не мала сенсу - я все одно переглядав погляди, навіщо мені потрібно повторювати?


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

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

@Jack, я вважаю, що мені довелося використовувати неатомне оновлення.
DCookie

Гммм, якщо я використовую стандартний матеріалізований вигляд, йому потрібно зробити атомне оновлення, тому це не спрацює для мене. Хтось ще може вважати його корисним, тому це все-таки хороша відповідь.
Лей Ріффер

Для чого потрібно атомне оновлення? Як я розумію, встановлення параметра "false" впливає лише на ПОЛЬНУ оновлення. Дивіться цю публікацію asktom: asktom.oracle.com/pls/apex/…
DCookie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.