| « Oracle11g : Paso a paso como utilizar el comando DUPLICATE ACTIVE DATABASE de RMAN | Tuning 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
19.08.09. 09:46:32. 1052 words, 2421 views. Categories: Oracle 10g, Tuning / Performance , Leave a comment » • Send a trackback »
Trackback address for this post
Trackback URL (right click and copy shortcut/link location)
Feedback awaiting moderation
This post has 1018 feedbacks awaiting moderation...