Limiter le rétablissement pour une actualisation complète de la vue matérialisée ou un équivalent manuel


10

Un journal de vue matérialisée (MV) peut être utilisé pour permettre à un MV d'effectuer une actualisation rapide qui ne modifie que les données modifiées. Cependant, diverses conditions empêchent le MV d'utiliser le journal et nécessitent donc une actualisation complète. Oracle a implémenté une actualisation atomique complète en tant que suppression et insertion de chaque enregistrement. Il le fait même s'il n'y a finalement aucun changement dans les données.

Existe-t-il un moyen de rendre cette réplication intelligente en ce qui concerne la génération de redo ? Un MERGE suivi d'un DELETE nécessite d'interroger la source deux fois. Vaut-il la peine de collecter les données en bloc pour effectuer une fusion et une suppression en bloc? Y a-t-il une meilleure façon?

Mettre à jour:

J'ai exploré l'utilisation d'une table temporaire globale comme zone de transit. Bien qu'ils utilisent moins de la moitié de la répétition, ils en utilisent encore beaucoup.


Pouvez-vous publier le code gtt? les gtt ne génèrent pas de redo directement, mais ils génèrent des annulations - et undo génère des redo. insertles opérations génèrent beaucoup moins d'annulation que les opérations deleteou update(presque aucune en fait). Avoir plusieurs gtts pour éviter des opérations coûteuses pourrait être une bonne approche
Jack dit essayer topanswers.xyz

@Jack Douglas psoug.org/reference/gtt.html a une démo de génération de redo GTT montrant une réduction de 60% du redo entre une table physique et une GTT pour inserts. Cela correspond étroitement aux résultats que je vois et est meilleur mais pas aussi bon que je le souhaiterais.
Leigh Riffel

Ces tests (ligne par ligne et sans appendindice) ne sont pas des conditions idéales pour réduire le rétablissement - j'ai effectué des tests pour montrer ce que je veux dire. Publié comme réponse car ils ne
rentreront

Réponses:


5

Ceci est juste destiné à démontrer l'utilisation de refaire de diverses insertopérations plutôt que de répondre à la question entière. Les résultats sur mon instance 10g ne sont pas 100% déterministes, mais la vue d'ensemble est restée la même à chaque fois que j'ai parcouru.

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

banc d'essai:

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

tester:

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                   

Vous avez raison bien sûr. J'aurais dû comprendre cela dans leurs tests. Je vais essayer.
Leigh Riffel

6

Bonne question. J'ai "résolu" ce problème pour ma situation il y a quelque temps en faisant les MV et tous les index sur eux NOLOGGING. Cela ne servait à rien ma situation - je faisais quand même un rafraîchissement complet de la vue, pourquoi aurais-je besoin de refaire?


1
Vous pouvez également avoir besoin d'ATOMIC_REFRESH = false (sur 10g et plus). Vous ne savez pas quelles sont les implications pour une base de données de secours ou une récupération avec des journaux d'archivage?
Jack dit d'essayer topanswers.xyz le

J'exécute une veille logique et physique sur la base de données avec laquelle je l'ai fait. Aucun problème là-bas. J'ai rencontré un problème avec la création de copies de base de données - je dois regarder mes notes, mais il y avait une erreur que j'obtenais parfois lors de la récupération sur un espace de table avec des tables de nologging. J'ai lu des recommandations pour créer un espace de table réservé aux tables / index qui ne se connectent pas pour éviter ces problèmes. J'ai bien compris comment le résoudre.
DCookie

@Jack, je crois que j'ai dû utiliser un rafraîchissement non atomique.
DCookie

Hmmm, si j'utilise une vue matérialisée standard, elle doit faire un rafraîchissement atomique, donc cela ne fonctionnera pas pour moi. Quelqu'un d'autre peut le trouver utile, c'est donc toujours une bonne réponse.
Leigh Riffel

Pourquoi a-t-il besoin d'un rafraîchissement atomique? Si je comprends bien, le définir sur false n'affecte que le rafraîchissement COMPLET. Voir cet article de asktom: asktom.oracle.com/pls/apex/…
DCookie
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.