Límite de rehacer para la vista materializada, actualización completa o equivalente manual


10

Se puede usar un registro de vista materializada (MV) para permitir que un MV realice una actualización rápida que solo modifica los datos que han cambiado. Sin embargo, varias condiciones impiden que el MV use el registro y, por lo tanto, requieren una actualización completa. Oracle implementó una actualización completa atómica como una eliminación e inserción de cada registro. Lo hace incluso si finalmente no hay cambios en los datos.

¿Hay alguna manera de hacer que esta replicación sea inteligente con respecto a la generación de rehacer ? Un MERGE seguido de DELETE requiere consultar la fuente dos veces. ¿Valdría la pena recopilar datos de forma masiva para hacer una BULK MERGE y DELETE? ¿Hay una mejor manera?

Actualizar:

Exploré el uso de una tabla temporal global como área de preparación. Aunque usan menos de la mitad del rehacer, todavía usan demasiado.


¿Puedes publicar el código gtt? Los gtt no generan rehacer directamente, pero generan deshacer, y deshacer genera rehacer. insertops generan mucho menos de deshacer que deleteo updateops (casi ninguno, de hecho). Tener múltiples gtts para evitar operaciones costosas podría ser un buen enfoque
Jack dice que intente topanswers.xyz

@Jack Douglas psoug.org/reference/gtt.html tiene una demostración de generación de rehacer GTT que muestra una reducción del 60% en rehacer entre una tabla física y un GTT por inserts. Esto coincide estrechamente con los resultados que estoy viendo y es mejor, pero no tan bueno como me gustaría.
Leigh Riffel

Esas pruebas (fila por fila y sin appendsugerencia) no son condiciones ideales para reducir el rehacer: he realizado algunas pruebas para mostrar lo que quiero decir. Publicado como respuesta porque no cabe en un comentario
Jack dice que intente topanswers.xyz

Respuestas:


5

Esto solo pretende demostrar el uso de rehacer varias insertoperaciones en lugar de responder a la pregunta completa. Los resultados en mi instancia de 10g no son 100% deterministas, pero el panorama general se mantuvo igual cada vez que lo encontré.

Para las tablas de montón, no sé por qué insert /*+ append */generaron más rehacer.

banco de pruebas:

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

prueba:

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

resultado:

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                   

Estás en lo cierto, por supuesto. Debería haber captado eso en sus pruebas. Lo probaré.
Leigh Riffel

6

Buena pregunta. "Resolví" este problema para mi situación hace un tiempo haciendo que los MV's y cualquier índice sobre ellos NOLOGGARA. No tenía sentido mi situación: estaba haciendo una actualización completa de la vista de todos modos, ¿por qué necesitaría rehacer?


1
Es posible que también necesite ATOMIC_REFRESH = false (en 10g y superiores). ¿No está seguro de cuáles son las implicaciones para cualquier base de datos en espera o recuperación con registros de archivo?
Jack dice que intente topanswers.xyz

Ejecuté un modo de espera lógico y físico en la base de datos con la que hice esto. No hay problemas allí. Me encontré con un problema al hacer copias de bases de datos; tengo que mirar mis notas, pero hubo un error que a veces obtenía al realizar la recuperación en un espacio de tabla con tablas de nologging. He leído recomendaciones para crear un espacio de tabla reservado para tablas / índices que no son de registro para evitar tales problemas. Sin embargo, descubrí cómo resolverlo.
DCookie

@ Jack, creo que tuve que usar una actualización no atómica.
DCookie

Hmmm, si uso una vista materializada estándar, necesita una actualización atómica, por lo que esto no funcionará para mí. Alguien más puede encontrarlo útil, por lo que sigue siendo una buena respuesta.
Leigh Riffel

¿Por qué necesita una actualización atómica? Según tengo entendido, establecer eso en falso solo afecta a una actualización COMPLETA. Vea esta publicación de asktom: asktom.oracle.com/pls/apex/…
DCookie
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.