« Oracle11g : Paso a paso como utilizar el comando DUPLICATE ACTIVE DATABASE de RMANTuning SQL : Lo malo de usar UNION en los select :) »

Monitorear o no monitorear , he allí el problema



Antes nos decían que debiamos monitorear la tabla para que quedase registro de las DMLs en la tabla *_TAB_MODIFICATIONS, y claro, eso es real hasta Oracle10gr1 , en Oracle10gr2 cambia un poco el tema.

Recordar un poco que el monitoring de una tabla, se realizaba con el comando


ALTER TABLE nombre_tabla MONITORING;

Y se puede apreciar si está o no monitoreada con el comando

select owner , table_name , monitoring from dba_tables where table_name like '%NOMBRE_TABLA%';

Cuando el parámetro STATISTIC_LEVEL está en TYPICAL, el monitoreo de todas las tablas es por defecto, lo que implica que siempre se almacenará su información de DMLs en la tabla *_TAB_MODIFICATIONS (Esto es sólo en Oracle10gr2)

Ejemplo de la consulta :

SQL> select owner , table_name , tablespace_name , monitoring from dba_tables where table_name like 'TABLA_FULL_%';

OWNER TABLE_NAME TABLESPACE_NAME MON
------------------------------ ------------------------------ ------------------------------ ---
SYS TABLA_FULL_7 SYSTEM YES
SYS TABLA_FULL_6 SYSTEM YES
SYS TABLA_FULL_5 SYSTEM YES
SYS TABLA_FULL_4 SYSTEM YES
SYS TABLA_FULL_3 SYSTEM YES
SYS TABLA_FULL_2 SYSTEM YES
SYS TABLA_FULL_1 SYSTEM YES

Y ejemplo de consulta en la tabla que lleva registro de las DMLs en una tabla

SQL> select table_name , inserts , updates , deletes from user_tab_modifications where table_name like '%TABLA_FULL_1%'

TABLE_NAME INSERTS UPDATES DELETES
------------------------------ ---------- ---------- ----------
TABLA_FULL_1 0 0 0

Para llevar a cabo un pequeño ejemplo del registro de las DML , procedemos a borrar una cantidad de registros de una tabla

SQL>delete tabla_full_6 where rownum < 1000 ;

Ejecutamos el vaciado desde memoria de la información de DMLs sobre las tablas

exec dbms_stats.flush_database_monitoring_info;

Está última instrucción siempre registra las DMLs hacía una tabla, aunque se le haya realizado rollback, saca la información desde memoria y la lleva a tablas físicas, este comando se puede dejar de lado y esperar que SMON vacíe la información cada 15 minutos aproximadamente.

Ejemplo de salida

SQL> r
1 select table_name , inserts , updates , deletes from user_tab_modifications
2* where table_name like '%TABLA_FULL_1%'

TABLE_NAME INSERTS UPDATES DELETES
------------------------------ ---------- ---------- ----------
TABLA_FULL_1 0 0 1000

Y quizás la pregunta es válida.. ¿Sirve saber la cantidad de delete a pesar de que haya rollback? , uno podría pensar hay fragmentación , una forma de analizar esto podría ser contando el número de bloques cuando :
- No se ha realizado operación sobre la tabla
- Se ha producido un borrado
- Se ha realizado el rollback

La verdad , se haga o no commit, siempre se registran los datos sobre la tabla

Miremos el siguiente ejemplo

Info original

SQL> r
1 select table_name , inserts , updates , deletes from user_tab_modifications where table_name like '%TABLA_FULL_1%'

TABLE_NAME INSERTS UPDATES DELETES
------------------------------ ---------- ---------- ----------
TABLA_FULL_1 0 0 1000

Procedemos a eliminar registro de la tabla 1 (TABLA_FULL_1) , hacer rollback y vaciar la info desde memoria

SQL> SQL> delete tabla_full_1 where rownum < 100;

99 rows deleted.

SQL> rollback;

Rollback complete.

SQL>
SQL>
SQL> exec dbms_stats.flush_database_monitoring_info;

PL/SQL procedure successfully completed.

SQL>

Y consultamos nuevamente la tabla de modificaciones

SQL> select table_name , inserts , updates , deletes from user_tab_modifications where table_name like '%TABLA_FULL_1%'
2 ;

TABLE_NAME INSERTS UPDATES DELETES
------------------------------ ---------- ---------- ----------
TABLA_FULL_1 0 0 1099

Como podemos ver, igual marca los datos a pesar de que haya un rollback

¿Y registrará las modificaciones en la *_tab_modifications pues hay un incremento o disminución de bloques?

Podemos comprobarlo mediante la siguiente consulta

SQL> col segment_name format a40
SQL> r
1* select blocks , bytes/1024/1024 MB , owner , segment_name from dba_segments where segment_name like 'TABLA_FULL_1'

BLOCKS MB OWNER SEGMENT_NAME
---------- ---------- ------------------------------ ----------------------------------------
768 6 SYS TABLA_FULL_1

7 rows selected.

Ahora procedemos a borrar , hacer rollback y realizar la misma consulta

SQL> delete tabla_full_1;

101220 rows deleted.

SQL> SQL> rollback;

Rollback complete.

SQL>
SQL>
SQL> select blocks , bytes/1024/1024 MB , owner , segment_name from dba_segments where segment_name like 'TABLA_FULL_1';

BLOCKS MB OWNER SEGMENT_NAME
---------- ---------- ------------------------------ ----------------------------------------
768 6 SYS TABLA_FULL_1

Y obtenemos exactamente la misma información

¿Y si desactivamos el monitoring de la tabla, sigue guardando registro en la *_tab_modification?
La respuesta es si, ya que desactivar el monitoring, simplemente no se puede

SQL> select owner , table_name , tablespace_name , monitoring from dba_tables where table_name like 'TABLA_FULL_1';

OWNER TABLE_NAME TABLESPACE_NAME MON
------------------------------ ------------------------------ ------------------------------ ---
SYS TABLA_FULL_1 SYSTEM YES

1 rows selected.

SQL> alter table tabla_full_1 nomonitoring;

Table altered.

SQL> select owner , table_name , tablespace_name , monitoring from dba_tables where table_name like 'TABLA_FULL_1';

OWNER TABLE_NAME TABLESPACE_NAME MON
------------------------------ ------------------------------ ------------------------------ ---
SYS TABLA_FULL_1 SYSTEM YES

Con el parámetro STATISTICS_LEVEL en BASIC , nada de esto se generá de forma automática. Y tener muy en cuenta que Oracle toma en cuenta los datos de esta tabla para verificar que tablas están con más de un 10% de modificaciones (tablas stale) ante lo cual le toma estadísticas

Una consulta bastante simple para saber a que tablas se les debiese tomar estadísticas de acuerdo a la cantidad de DMLs ejecutadas , es la siguiente

col porcentaje format 9999D999

select u.TIMESTAMP,
t.last_analyzed,
u.table_name,
u.inserts,
u.updates,
u.deletes,
d.num_rows,
TO_CHAR(((U.inserts+u.deletes+u.updates)/decode(nvl(d.num_rows,0),0,1,d.num_rows)) * 100,'999D99') percent
from user_tables t,USER_TAB_MODIFICATIONS u,dba_tables d
where u.table_name = t.table_name
and d.table_name = t.table_name
and d.owner = 'SYS'
and (u.inserts is not null or u.updates is not null or u.deletes is not null)
and ((U.inserts+u.deletes+u.updates)/decode(nvl(d.num_rows,0),0,1,d.num_rows)) * 100 > 10
order by t.last_analyzed , ((U.inserts+u.deletes+u.updates)/decode(nvl(d.num_rows,0),0,1,d.num_rows)) * 100

Puede tener variaciones y ciertas especulaciones, pero es una orientadora...

Otro punto a tener en cuenta, es cuando se toman estadísticas, se elimina la información sobre la *_TAB_MODIFICATIONS

Espero les sea de utilidad

by Ligarius
19.08.09. 09:46:32. 1052 words, 7760 views. Categories: Oracle 10g, Tuning / Performance ,