본문 바로가기

카테고리 없음

ORACLE 9iClustering Factor (CF)

Clustering Factor (CF)

 

from Practical OWI | exem | exem

 

1.   정의

CLUSTERING FACTOR - 모든 인덱스 로우에 대해 순차적으로 데이터(테이블) 로우를 엑세스할 때 DISK READ를 일으켜 읽어 들어야 하는 총 데이터 블록의 수

 

2.   특징

A.     CLUSTERING FACTOR 의 값은 NUMBER 타입이며 블록수보다 작을 수 없다.

 

아래의 쿼리에서는 해당 INDEX 가 사용하는 블록의 수를 조회해 보았다.

 

SQL> select segment_name, blocks

from dba_segments

where segment_name = 'TEST_ID1_IDX’

 

SEGMENT_NAME             BLOCKS

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

TEST_ID1_IDX                512

 

아래의 쿼리에서는 해당 인덱스의 clustering_factor를 조회해 보았다.

 

SQL> select index_name,clustering_factor

  2  from dba_indexes

  3  where index_name = 'TEST_ID1_IDX';

 

INDEX_NAME                     CLUSTERING_FACTOR

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

TEST_ID1_IDX                                 690

 

B.      INDEX REBUILD 해도 TABLE CF가 개선되지 않으면 성능개선에 큰 영향을 줄 수 없다.

 

SQL> select index_name,clustering_factor

  2  from dba_indexes

  3  where index_name = 'TEST_ID1_IDX';

 

INDEX_NAME                     CLUSTERING_FACTOR

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

TEST_ID1_IDX                                 690

 

SQL> alter index test.test_id1_idx rebuild;

 

Index altered.

 

SQL> select index_name, clustering_factor

  2  from dba_indexes

  3  where index_name = 'TEST_ID1_IDX';

 

INDEX_NAME                     CLUSTERING_FACTOR

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

TEST_ID1_IDX                                 690

 

SQL> select index_name,status

  2  from dba_indexes

  3  where index_name = 'TEST_ID1_IDX';

 

INDEX_NAME                     STATUS

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

TEST_ID1_IDX                   VALID

 

SQL> select table_name, tablespace_name       

  2  from dba_tables

  3  where owner = 'TEST';

 

TABLE_NAME                     TABLESPACE_NAME

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

PLAN_TABLE                     DEL

TEST                           DEL

 

아래의 명령어에서 해당 테이블을 그 자리에 들었다 놓았다이 동작은 사용공간을 최적화 하는 효과가 있다.

 

SQL> alter table test.test move tablespace del;

 

Table altered.

 

아래의 쿼리에선 위에서 참조되는 대상이었던 테이블에 DDL 이 일어나면서 이를 참조하던 TEST_ID1_IDX INVALID  상태가 되었다. 이를 다시 사용하기 위해서는 REBUILD 가 필요하다.

 

SQL> select index_name,status

  2  from dba_indexes

  3  where index_name = 'TEST_ID1_IDX';

 

INDEX_NAME                     STATUS

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

TEST_ID1_IDX                   UNUSABLE

 

아래의 쿼리에서 REBUILD 하였다.

 

SQL> alter index test_id1_idx rebuild;

 

SQL> select index_name,status

  2  from dba_indexes

  3  where index_name = 'TEST_ID1_IDX';

 

INDEX_NAME                     STATUS

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

TEST_ID1_IDX                   VALID

 

아래의 쿼리에선 저장공간을 최적화 하면서 오히려 악화되었다. 이 값이 의미하는 것은 해당 INDEX( SORT 된 상태 ) ROWID 를 따라갈 때 블록을 여기저기서 들춰본다는 것이다. ( 비효율 )

 

SQL> @clust

 

INDEX_NAME                     CLUSTERING_FACTOR

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

TEST_ID1_IDX                               61028

 

 

3.   개선안

A.     SELECT를 이용한 방법

 

SQL> conn test/test

Connected.

SQL> select count(*) from test;

 

  COUNT(*)

----------

    100000

 

값을 정렬해서 테이블을 만들었다.

SQL> create table test2

  2  as select * from test

  3  order by 1 asc;

 

Table created.

 

SQL> commit;

 

Commit complete.

 

SQL> create index test2_id1_idx on test2(id1);

 

Index created.

 

SQL> conn /as sysdba

Connected.

 

아래의 쿼리에서 통계정보를 수집하였다.

이 과정없이 clustering_factor 를 조회하면 값이 비어있다. ( 인덱스 갓 생성시 )

 

SQL> analyze index test.test2_id1_idx compute statistics;

 

Index analyzed.

 

from 절의 인덱스를 새로만든 이름으로 수정하였다.

SQL> ed clust

 

SQL> @clust

 

INDEX_NAME                     CLUSTERING_FACTOR

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

TEST2_ID1_IDX                                975

 

move tablespace 로 급상한 clustering factor와 달리 ordered 된 값을 가지고 테이블을 만든 경우 위와 같은 값을 얻었다.

 

위와 같은 방법을 사용해도 여전히 실제 사용 블록수와는 상당한 차이가 있다.

 

/*+ 방법을 더 찾아보자 !! */