Kabaca ; indeks üzerinden tabloya gidildiğinde ,her gidişte okunan tablo bloklarının sayısıdır.Arka arkaya aynı bloktan okuma yapılırken CF degeri arttırılmaz.Ne zamanki farklı bloga geçildi ,değeri o zaman bir arttırılır.Peki bundan bize ne:) Aslında bayağı ilgili olmamız gereken bir bilgi.Çünkü verilere ulaşırken tablonun ne kadar bloğu üzerinde gezineceğimiz (I/O) ortaya çıkıyor.Ne kadar çok blok okuma o kadar COST = maliyet.Bu da execution planı etkilemektedir.
Daha iyi ifade etmek için aşağıdaki gibi bir örnek yapalım.Tablomuz aşağıdaki gibi değerlerden oluşsun ve satırlar 3 bloğa dağılmış olsun.
DESCR ID DESCR ID DESCR
1 “bir” 4 “dört” 7 “yedi”
2 “iki” 5 “beş” 8 “sekiz”
3 “üç” 6 “altı” 9 “dokuz”
Block1 Block2 Block3
“ID” kolonu uzerinde indeksimiz oldugunu ve indeks üzerinden cift ID lerin DESCR kolon değerine ulasmaya çalıştığımızı düşünelim.
Indeksten tabloya hareket CF adedi (kümülatif)
2 ye tabloda ulaşıldıgında 1 (Block 1)
4 e tabloda ulaşıldıgında 2 (Block 2)
6 ya tabloda ulaşıldıgında 2 (Block 2)
8 e tabloda ulaşıldığında 3 (Block 3)
4 ve 6 aynı blokta oldugu için 2. adımdan 3. adıma geçerken CF değeri artmadı.Sonuç olarak CF değeri tablodaki blok sayısı kadar oldu.Bir başka değişle çift degerleri almak için tablodaki tüm blokları ziyaret ettik! (COST = Maliyet)
Tablo yapımız aşağıdaki gibi olsaydı CF “1” olacaktı. Başka bir değişle Cost = maliyet daha az olurdu.
DESCR ID DESCR
1 “bir” 2 “iki”
3 “üç” 4 “dört”
5 “beş” 6 “altı”
7 “yedi” 8 “sekiz”
9 “dokuz”
Şimdi bu abnatılanları gerçek dünyada görelim. TTEST tablomuzu ve bu tablo üzerinde indeksi oluşturalım :
SQL> create table TTEST as select * from all_objects order by object_id;
Table created.
SQL> create index TTEST_ID_IDX on TTEST(object_id);
Index created.
İstatistik toplamayı unutmuyoruz.
SQL> analyze table TTEST compute statistics for all indexes;Table analyzed.
Şimdide aşağıdaki sorgu ile tablodaki blok adedi ve CF değerini görelim :
SQL> select t.blocks table_blocks, i.clustering_factor CF
2 from dba_tables t, dba_indexes i
3 where t.table_name=i.table_name
4 and t.table_name=’TTEST’
5 and t.owner = ‘TEST’;
TABLE_BLOCKS CF
———— —————-
33816 157
Tablomuzu biraz karıştıralım.Bunu için tablomuza aşağıdaki gibi verilerei girelim :
SQL> insert into ttest select * from all_objects order by object_type;
11797 rows created.
İstatistiğimizi toplayalım.
SQL> analyze table TTEST compute statistics for all indexes;
Table analyzed.
Tablodaki blok adedi ve CF değerini yeniden görelim :
SQL> select t.blocks table_blocks, i.clustering_factor CF
2 from dba_tables t, dba_indexes i
3 where t.table_name=i.table_name
4 and t.table_name=’TTEST’
5 and t.owner = ‘TEST’;
TABLE_BLOCKS CF
———— ——————
33816 22912
CF oldukça arttı.Bunun olası bir maliyetide beraberinde getireceğini artık farkındayız.
Peki CF degerini nasıl düşürebiliriz?Akla gelen ilk yol tabloyu yeniden organize etmektir.Bunu da 10g ile gelen shrink opsiyonu ile gerçekleştirebiliriz.Ancak SHRINK kullanabilmek için tablespace’in ASSM modda olması gerektigini unutmayalım. Bazende çok DML görmüş bir tabloyu (özellikle sık update ,delete) yeniden oluşturmak iyi olabilir.
Hakkı Oktay
http://hakkioktay.wordpress.com
|