Dba_Tab_Modifications ve Gather_Stats

Dba_Tab_Modifications ve Gather_Stats

Tabloya en son gelen insert update zamanlari gerekebilir. Bir tablo ne zamandan beri DML almiyor görmek istenebilir. Bunun için neler yapilabilir. Dba_tables dict viewdan last_analyzed kolonuna bakilabilir veya DBA_TAB_MODIFICATIONS  ( ayni tablonun all ve user versiyonlari da mevcut.) tablosuna bakilabilir. Iste bu yazida bu viewlar hakkinda biraz bilgi sahibi olacagiz, farkli durumlarda son DML bilgisini nasil alacagimizi bulacagiz.

DML islemleri data üzerinde degisiklik yaptigindan tablo istatistigini degistirir. Bu durumda tablo üzerindeki son DML hareketlerini görmek istedigimizde karsimiza iki durum çikacaktir;

  1. Istatistik aliniyorsa
  2. Istatistik alinmiyorsa

Önemi oldugunu düsündügümüz bir veritabaninda istatistik alinmali, dolaysiyla sadece istatistik aliniyorsa nasil ilerleyecegimize bakalim.

Öncelikle last_analyzed kolonu yardimci olabilir;

TABLE_NAME LAST_ANALYZED
DENEME 03.12.2013 19:00:09
DENEME1 05.02.2011 23:06:16
DENEME2 05.02.2011 20:55:55
DENEME3 05.02.2011 20:24:52
DENEME4 05.02.2011 20:15:21

DENEME1-4 tablolari 20010205’ten bu yana hiç degismemis  görünüyor.  Bu sekilde düsünülebilir ama bu bizi yaniltir. Çünkü last_analyzed kolonunu gather_stats degistirir. Fakat gather_stast her degisiklikten sonra çalismaz. Default olarak degisiklik miktari tablonun row sayisnin %10’una ulastiktan sonra çalisir.  Estimate_percent degerni görmek için asagidaki query çalistirilabilir.

SQL> select dbms_stats.get_param('estimate_percent') from dual;
DBMS_STATS.GET_PARAM('ESTIMATE_PERCENT')

--------------------------------------------------------------------------------
DBMS_STATS.AUTO_SAMPLE_SIZE

Iste tablonun estimate_percent degerinden küçük olan DML’ler almasi durumunda DBA_TAB_MODIFICATIONS   dict view’indan faydalanabiliriz.

SQL> select * from SYS.DBA_TAB_MODIFICATIONS where table_owner='OPER';

no rows selected

himm, OPER userinin tablolarina hiç DML gelmemis görünüyor. Fakat bu bizi yaniltmasin,

SQL> select count(*) from OPER.DENEME;

  COUNT(*)

----------
 0

SQL> insert into OPER.DENEME values(123, 'qwerty');

1 row created.

SQL> insert into OPER.DENEME values(456, 'asdfg');

1 row created.

SQL> select count(*) from OPER.DENEME;

  COUNT(*)

----------

         2

SQL> select * from SYS.DBA_TAB_MODIFICATIONS where table_owner='OPER';

no rows selected

2 row insert etmemize ragmen sanki hiç DML yapilmamis gibi sonuç dönüyor.  Çünkü oracle her DML isleminden sonra bu tabloyu güncellemiyor. Çok fazla DML alan tablolar varsa sadece bu islem bile çok kaynak tüketecektir.  Oracle yapilan tüm DML islemlerini memory’de tutar. Ta ki manuel veya otomatik çalisan bir job flush yapana kadar. Manuel flush yapmak için;


SQL> exec dbms_stats.flush_database_monitoring_info;
PL/SQL procedure successfully completed
SQL> select * from SYS.DBA_TAB_MODIFICATIONS where table_owner='OPER';

TABLE_OWNER                    TABLE_NAME                     PARTITION_NAME                 SUBPARTITION_NAME                 INSERTS    UPDATES    DELETES TIMESTAMP TRU DROP_SEGMENTS

------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------- ---------- ---------- --------- --- -------------
OPER                           DENEME                                                                                                2          0          0 13-MAR-13 NO              0

Ewet, yaptigimiz degisiklikler görülebiliyor.  Simdi birkaç degisiklik daha yapalim;

SQL> update OPER.DENEME set id=789 where id=123;
1 row updated.
SQL> instert int
OPER.DENEME values(45678,'deneme123');
SQL> insert into OPER.DENEME values(45678,'deneme123');
1 row created.
SQL> insert into OPER.DENEME values(85858, 'test123');
1 row created.
SQL> delete from OPER.DENEME where id=456;
1 row deleted.
SQL> select count(*) from OPER.DENEME;
  COUNT(*)
----------
         3
SQL> select * from SYS.DBA_TAB_MODIFICATIONS where table_owner='OPER';

TABLE_OWNER                    TABLE_NAME                     PARTITION_NAME                 SUBPARTITION_NAME                 INSERTS    UPDATES    DELETES TIMESTAMP TRU DROP_SEGMENTS

------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------- ---------- ---------- --------- --- -------------

OPER                           DENEME                                                                                                2          0          0 13-MAR-13 NO              0

Yaptigimiz DML islemlerin görülememesinin nedeni yukarda bahsettigim gibi oracle’in DML yapildiktan hemen sonra dba_tab_modifications tablosuna yansitmamasi. Ancak flush yaptiktan sonra yansiyacaktir;

SQL> exec dbms_stats.flush_database_monitoring_info;
PL/SQL procedure successfully completed.
SQL> select * from SYS.DBA_TAB_MODIFICATIONS where table_owner='OPER';

TABLE_OWNER                    TABLE_NAME                     PARTITION_NAME                 SUBPARTITION_NAME                 INSERTS    UPDATES    DELETES TIMESTAMP TRU DROP_SEGMENTS

------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------- ---------- ---------- --------- --- -------------
OPER                           DENEME                                                                                                4          1          1 13-MAR-13 NO              0

Simdi de DBA_TAB_MODIFICATIONS tablosunun nasil resetlendigini görelim.

 

SQL> select table_name, last_analyzed from dba_tables 
where owner='OPER' and table_name='DENEME' order by 2 desc;

TABLE_NAME                     LAST_ANALYZED
------------------------------ -------------------
DENEME                         03-12-2013 19:00:09

SQL> select table_name, last_analyzed from dba_tables where owner='OPER' and table_name='DENEME' order by 2 desc;

TABLE_NAME                     LAST_ANALYZED
------------------------------ -------------------
DENEME                         03-12-2013 19:00:09

SQL> exec dbms_stats.gather_table_stats('OPER', 'DENEME');
PL/SQL procedure successfully completed.
SQL> select table_name, last_analyzed from dba_tables where owner='OPER' and table_name='DENEME' order by 2 desc;

TABLE_NAME                     LAST_ANALYZED
------------------------------ -------------------
DENEME                         03-13-2013 17:50:48
SQL> select * from SYS.DBA_TAB_MODIFICATIONS where table_owner='OPER';
no rows selected

SQL> exec dbms_stats.flush_database_monitoring_info;
PL/SQL procedure successfully completed.
SQL> select * from SYS.DBA_TAB_MODIFICATIONS where table_owner='OPER';
no rows selected

SQL> select count(*) from OPER.DENEME;
  COUNT(*)
----------
         3

SQL> delete from OPER.DENEME where id=45678;
1 row deleted.

SQL> select count(*) from OPER.DENEME;
  COUNT(*)
----------
         2

SQL> select * from SYS.DBA_TAB_MODIFICATIONS where table_owner='OPER';
no rows selected
SQL> exec dbms_stats.flush_database_monitoring_info;

PL/SQL procedure successfully completed.

SQL> select * from SYS.DBA_TAB_MODIFICATIONS where table_owner='OPER';

TABLE_OWNER                    TABLE_NAME                     PARTITION_NAME                 SUBPARTITION_NAME                 INSERTS    UPDATES    DELETES TIMESTAMP           TRU DROP_SEGMENTS

------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------- ---------- ---------- ------------------- --- -------------

OPER                           DENEME                                                                                                0          0          1 03-13-2013 17:54:10 NO              0

Son testimizde görülecegi üzere  dbms_stats %10 degisiklik oldugu için yeniden analiz edildi. Dolayisyla DBA_TAB_MODIFICATIONS tablosu da resetlendi.  Yeni yapilan DML islemleri ise yukarda da gördügümüz gibi ancak flush isleminden sonra DBA_TAB_MODIFICATIONS tablosunda görülebildi.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir