web-dev-qa-db-fra.com

LIMITE REDO POUR VOIR MATÉRIALISÉE Complete Rafraîchir ou équivalent manuel

Une vue matérialisée(Mv) Le journal peut être utilisé pour permettre à un MV de faire un rafraîchissement rapide qui modifie uniquement les données qui ont changé. Cependant, diverses conditions empêchent le MV d'utiliser le journal et nécessitent donc une actualisation complète. Oracle a mis en place un rafraîchissement complet atomique comme une suppression et une insertion de chaque enregistrement. Cela le fait même s'il y a finalement aucune modification des données.

Existe-t-il un moyen de faire cette réplication intelligente en ce qui concerne la génération de refonte? Une fusion suivie d'une suppression nécessite une interrogation de la source deux fois. Serait-il en vaut la peine de collecter les données pour faire une fusion en vrac et supprimer? Y a-t-il une meilleure façon?

Mettre à jour:

J'ai exploré à l'aide d'une table temporaire mondiale comme zone de mise en scène. Bien qu'ils utilisent moins de la moitié du Redo, ils utilisent encore beaucoup.

10
Leigh Riffel

Ceci est juste destiné à démontrer l'utilisation de Refaire de diverses opérations insert plutôt que de répondre à l'ensemble de la question. Les résultats sur mon instance 10G ne sont pas déterministes à 100%, mais la large image est restée la même chaque fois que j'ai couru.

Pour les tables de tas, je ne sais pas pourquoi le insert /*+ append */ généré plus de redo.

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);

test:

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';

résultat:

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                   

Bonne question. J'ai "résolu" ce problème pour ma situation en revenant en rendant les MV et les indices qui leur sont nulologués. Il n'y a pas eu de point à ma situation - je faisais un rafraîchissement complet de la vue quand même, pourquoi aurais-je besoin de refaire?

6
DCookie