DATABASE/Oracle2011/12/01 04:43

-- 8i --
SELECT num
     , MIN(DECODE(rn,1,''''||data||''''))
    || MIN(DECODE(rn,2,','''||data||''''))
    || MIN(DECODE(rn,3,','''||data||''''))
  FROM (SELECT num, data
             , ROW_NUMBER() OVER(PARTITION BY num ORDER BY data) rn
          FROM t
        )
 GROUP BY num
;

-- 9i --
SELECT num
     , SUBSTR(MAX(SYS_CONNECT_BY_PATH(''''||data||'''',',')),2) data
  FROM (SELECT num, data
             , ROW_NUMBER() OVER(PARTITION BY num ORDER BY data) rn
          FROM t
        )
 START WITH rn = 1
 CONNECT BY PRIOR num = num
        AND PRIOR rn = rn - 1
 GROUP BY num
;

-- 10G --
SELECT num
     , REPLACE(SUBSTR(data,2),'@','''') data
  FROM
(
SELECT num,
XMLAGG(XMLELEMENT(x,',@'||data||'@') ORDER BY data).EXTRACT('//text()').GetStringVal() data
  FROM t
 GROUP BY num
)
;

10G XML 함수에서는 따옴표가 ' 로 표시되는 관계로
부득이하게 @ 로 대체해서 다시한번 처리했습니다.


 

크리에이티브 커먼즈 라이센스
Creative Commons License
2011/12/01 04:43 2011/12/01 04:43
Posted by

Leave your greetings.

DATABASE/Oracle2011/06/19 03:56
Oracle DBA Scripts

Oracle-Base.com에 소개된 Oracle DBA Scripts자료이다.
버젼별로 잘 정리가 되었으니 실무에 아주 유용한 자료가 아닐까 생각한다.

링크 : http://www.oracle-base.com/dba/Scripts.php
크리에이티브 커먼즈 라이센스
Creative Commons License
2011/06/19 03:56 2011/06/19 03:56
Posted by
Tags , ,

Leave your greetings.

DATABASE/Oracle2009/11/26 16:23

인간의 생각하는 능력이 언어라는 것을 만들었지만, 거꾸로 언어가 인간의 사고 능력을 지배하게 되죠.

오라클 성능 세계에서도 마찬가지입니다. 용어에 대한 정확한 이해가 없으면 문제를 100% 이해할 수도 없을뿐더러 잘못된 지식을 믿게 됩니다. 예를 들어 볼까요?

Explain Plan과 Execution Plan의 차이를 설명할 수 있습니까?
Scan과 Lookup의 차이는 무엇입니까?
Histogram의 의미는 무엇입니까?
Lock과 Enqueue의 의미를 구분할 수 있습니까?
SQL문과 Cursor의 차이를 설명할 수 있습니까?
Event라는 용어가 언제 쓰이는지 설명할 수 있습니까?
용어을 100% 정확하게 설명할 수 있다면 그 자체로도 성능 문제에 대한 상당한 통찰력을 가지고 있다고 볼 수 있습니다.

출처:http://ukja.tistory.com/282


부끄럽다...^^;;

크리에이티브 커먼즈 라이센스
Creative Commons License
2009/11/26 16:23 2009/11/26 16:23
Posted by
Tags ,

Leave your greetings.

DATABASE/Oracle2009/03/20 16:08

우리가 가끔 날짜관련 계산을 하다보면 첫번째 월요일이라든가 마지막 주 월요일이라든가...
뭐 이런 날을 가져와야 할 경우가 있다. 그전에는 날짜 테이블이 있어 쉽게 가져올 수 가있었는데
그렇지 않은 경우는 천상 쿼리로 구현할 수 밖에 없다.
여기에서 핵심 함수는 last_day(date), next_day(date,char) 이다.
그 용법은 간단히 소개하면

last_day()
: 지정한 일자가 포함된 월의 말일
예)
select last_day(sysdate) from dual  -- 지금은 2009년3월20일이다.
09/03/31

next_day(date,char)
: 지정한 일자 다음에 나타나는 지정 요일(두번째 인수)
예)
select next_day((last_day(sysdate)),'금요일') from dual
select next_day((last_day(sysdate)),'금') from dual
select next_day((last_day(sysdate)),6) from dual  -- 일:1 ~ 토:7
09/04/03
뭐 이런식이다

위의 함수를 응용하면 2009년3월의 첫번째 월요일과 마지막주 월요일은 아래와 같이
구할 수 있다.

-- 첫주 월요일
select next_day((trunc(sysdate,'mm')-1),'월') from dual
-- 마지막주 월요일
select next_day((last_day(sysdate)-7),'월') from dual


크리에이티브 커먼즈 라이센스
Creative Commons License
2009/03/20 16:08 2009/03/20 16:08
Posted by

Leave your greetings.

DATABASE/Oracle2009/02/24 09:37
Full Outer Join에 대해 좋은 글이 있어 링크!

Full Outer Join의 비밀



크리에이티브 커먼즈 라이센스
Creative Commons License
2009/02/24 09:37 2009/02/24 09:37
Posted by

Leave your greetings.

DATABASE/Oracle2009/01/30 02:32

### Lock 확인 쿼리
SELECT do.object_name, do.owner, do.object_type,do.owner, vo.xidusn, vo.session_id,
vo.locked_mode
FROM v$locked_object vo , dba_objects do
WHERE vo.object_id = do.object_id ;

####  어떤 object에 어떤 lock이 걸렸는지 확인
SELECT  T1.object_name, DECODE(locked_mode, 2, 'ROW SHARE', 3, 'ROW EXCLUSIVE',  4, 'SHARE', 5, 'SHARE ROW EXCLUSIVE', 6, 'EXCLUSIVE', 'UNKNOWN') lock_mode
FROM  dba_objects T1, v$locked_object T2
WHERE T1.object_id = T2.object_id;

#### session 확인
select * from v$session where status = 'ACTIVE'

#### cursor 확인
v$open_cursor

#### 테이블의 lock 확인
SELECT A.SID, A.SERIAL#, B.TYPE, C.OBJECT_NAME
FROM V$SESSION A, V$LOCK B, DBA_OBJECTS C
WHERE A.SID=B.SID
AND B.ID1=C.OBJECT_ID
AND B.TYPE='TM'
AND C.OBJECT_NAME IN ('<테이블이름>');

/*******************************************************************************
* LOCK 관련
*******************************************************************************/
--V$LOCK 을 사용한 잠금 경합 모니터링
SELECT s.username, s.sid, s.serial#, s.logon_time,
  DECODE(l.type, 'TM', 'TABLE LOCK',
         'TX', 'ROW LOCK',
      NULL) "LOCK LEVEL",
  o.owner, o.object_name, o.object_type
FROM v$session s, v$lock l, dba_objects o
WHERE s.sid = l.sid
AND o.object_id = l.id1
AND s.username IS NOT NULL   

--락이 걸린 세션 자세히 알아보기
select a.sid, a.serial#,a.username,a.process,b.object_name,
decode(c.lmode,2,'RS',3,'RX',4,'S',5,'SRX',8,'X','NO') "TABLE LOCK",
decode (a.command,2,'INSERT',3,'SELECT',6,'UPDATE',7,'DELETE',12,'DROP TABLE',26,'LOCK TABLE','UNknown') "SQL",
decode(a.lockwait, NULL,'NO wait','Wait') "STATUS"
from v$session a,dba_objects b, v$lock c
where a.sid=c.sid and b.object_id=c.id1
and c.type='TM'

--락이 걸린 세션 간단히 알아보기
select a.sid, a.serial#, b.type, c.object_name, a.program, a.lockwait,
      a.logon_time, a.process, a.osuser, a.terminal
from v$session a, v$lock b, dba_objects c
where a.sid = b.sid
  and b.id1 = c.object_id
  and b.type = 'TM';

select a.sid, a.serial#, a.username, a.process, b.object_name
from v$session a , dba_objects b, v$lock c
where a.sid=c.sid and b.object_id = c.id1
and c.type = 'TM'

--락이 걸린 세션을 찾아 내어 세션을 죽이려고 해도 죽지 않는 경우
--아래 쿼리문으로 OS단의 PROCESS ID를 찾아내어 OS에서 죽인다
--kill -9 프로세스아이디
select substr(s.username,1,11) "ORACLE USER", p.pid "PROCESS ID",
s.sid "SESSION ID", s.serial#, osuser "OS USER",
p.spid "PROC SPID",s.process "SESS SPID", s.lockwait "LOCK WAIT"
from v$process p, v$session s, v$access a
where a.sid=s.sid and
p.addr=s.paddr and
s.username != 'SYS'

--위 쿼리문의 결과가 있다면 락이 걸린 세션이 있다는것이므로 아래의 쿼리문으로 세션을 죽인다
ALTER SYSTEM KILL SESSION '11,39061'

/**************************************************************************************/

출처 : http://cocoroworld.com/blog/root/entry/오라클-락lock

크리에이티브 커먼즈 라이센스
Creative Commons License
2009/01/30 02:32 2009/01/30 02:32
Posted by

Leave your greetings.

DATABASE/Oracle2009/01/30 02:18

ORA-28000에러는 일정 회수이상 로그인 실패시 계정에 lock이 걸리면서
"ORA-28000: the account is locked"
라는 메시지를 뱉어낸다.
(10g일 경우 설치 후 처음 scott계정을 사용할 때도 이런 에러가 뜬단다. 난 본적이 없어 모르겠다^^;)

1. 일단 sysdba로 접속한다.
sqlplus "/ as sysdba"

2. lock걸린 user를 찾아낸다.
SELECT username, account_status, to_char(lock_date,'yy/mm/dd hh24:mi') lock_date
FROM dba_users;

사용자 삽입 이미지


user가 MODELINGWORLD인 놈이 lock이 걸린걸 확인할 수 있다.

3. lock을 해제한다.
ALTER USER MODELINGWORLD account unlock;

4. 패스워드변경(아무래도 찜찜하니 패스워드도 변경해야겠지)
ALTER USER SYSTEM IDENTIFIED BY ****;


- 문
그럼 도대체 몇번 로그인을 실패하면 lock이 걸리는 거냐?

- 답
SQL> SELECT p.profile, p.resource_name, p.limit
  2  FROM dba_users u, dba_profiles p
  3  WHERE p.profile = u.profile
  4  AND username='modelingworld';
위와 같은 쿼리를 날리면
결과 중에 'FAILED_LOGIN_ATTEMPTS' 컬럼이 제한 개수이다.

그럼 제한을 풀 수도 있지않을까? 당근 있다.
ALTER profile default limit FAILED_LOGIN_ATTEMPTS UNLIMITED;
크리에이티브 커먼즈 라이센스
Creative Commons License
2009/01/30 02:18 2009/01/30 02:18
Posted by
Tags , ,

Leave your greetings.

DATABASE/Oracle2008/11/19 15:48

◈ enqueue 와 latch
- DBMS의 가장 주된 기능 중에 하나는 동일 자원에 대한 동시 액세스를 관리하는 것이며, 이를 위해 오라클이 사용하는 대표적인 제어 구조가 Enqueue와 Latch 입니다.

- enqueue는 FIFO 구조를 가진 큐 입니다. 먼저 요청한 쪽이 먼저 자원을 획득하는 방식 입니다. 그러나 latch는 enqueue와 달리 자유 경쟁에 의해 latch를 획득하게 되며 먼저 요구했다고 해서 반드시 먼저 획득할 수 있는 것이 아닙니다.

◈ 래치란?
- 래치(Latch) = 빗장, 락(Lock) = 자물쇠

- 래치는 SGA 내부의 메모리 구조에만 적용된다. 래치는 데이터베이스 오브젝트에는 적용되지 않습니다. 오라클 SGA는 많은 래치를 가지고 있으며 이것은 동시 접근에 의한 잠재적인 충돌로 부터 다양한 메모리 구조를 보호하기 위해 사용 합니다.

- 래치가 보호하는 리소스 .SGA 내의 모든 메모리 영역은 Latch를 통해서 획득됨 .Buffer Cache, Shared Pool, Library Cache, Log Buffer - SGA 영역을 탐색하는 모든 행위는 래치 획득 후에만 가능

- 래치 관련 Dynamic Performance Views .V$LATCH : 래치 종류별 통계값

출처 : http://web.oracleclub.com/glossaryview.action?glossary.glossaryId=1441

크리에이티브 커먼즈 라이센스
Creative Commons License
2008/11/19 15:48 2008/11/19 15:48
Posted by

Leave your greetings.

DATABASE/Oracle2008/01/16 14:14

Materialized view

query문의 실행결과에서 내부적으로 과도한 sort가 발생하거나 실행결과가 나오기까지 오랜 시간이 걸린다면

이 query문을 한번만 쓰고 버리기 아까울 것이다. 이럴경우 실행결과를 Table 처럼 view로 구성하는 것을

Materialized view라 한다. (9i부터)

 

 * SQL문의 "인스턴스화"

 * 고유한 데이터 세그먼트가 있으며, 다음 이점을 제공함

    - 공간관리 옵션

    - 고유한 인덱스 사용

 * 다음 작업에 유용함

    - 비용이 많이 드는 복잡한 조인

    - 데이터 요약 및 집계 

그러나 query 요구가 달라지면 새로운 Materialized view를 다시 생성해야함

 -> query 당 하나의 Materialized view 사용

또한, DML 문장 실행시 심각한 Refresh 발생


<< Materialized view 실습 >>

$ sqlplus '/ as sysdba'
SQL> alter system set query_rewrite_enabled=true;
SQL> grant create materialized view to scott;
SQL> grant query rewrite to scott;


Materialized view를 사용하려면 기본적으로 Materialized view권한과 query rewrite 권한을 부여 받아야 한다.

query rewrite는 비용 기준 최적화를 사용하는 경우에 사용되며

활성화 및 제엉 방법은

query_rewrite_enabled = {true| false|force} -->Dynamic 인스턴스/세션 Parameter

  - true(기본값) : 비용기준 Rewrite(Cost-based Rewrite)

  - false : Rewrite 없음

  - force : 강제 Rewrite

query_rewrite_integerity = {enforced|trusted|stale_tolerated}  -->Dynamic 인스턴스/세션 Parameter

: query rewrite 할때 문제점 발생시 어떻게 처리할지 결정하는 변수


  - enforced(기본값) : 옵티마이저가 일관성을 보장할 수 있는 경우에만 query rewrite 활성화

  - trusted : 최신의 Materialized view와 활성화 되고 검증된 제약조건에만 query rewrite 활성화

  - stale_tolerated : 차이점을 인정하고 그냥 Materialized view 실행


SQL> connect scott/tiger


-- CBO 옵티마이져 사용을 위한 통계 수집
SQL> execute dbms_stats.gather_table_stats('scott','emp');
SQL> execute dbms_stats.gather_table_stats('scott','dept');


SQL> set autot trace explain


SQL> select d.deptno, sum(e.sal) dept_tot
from emp e, dept d
where e.deptno=d.deptno
group by d.deptno;

  DEPTNO   DEPT_TOT
---------- ----------
        10       8750
        20      10875
        30       9400

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=3 Bytes=30)
   1    0   SORT (GROUP BY) (Cost=4 Card=3 Bytes=30)
   2    1     NESTED LOOPS (Cost=3 Card=14 Bytes=140)
   3    2       TABLE ACCESS (FULL) OF 'EMP' (Cost=3 Card=14 Bytes=98)
   4    2       INDEX (UNIQUE SCAN) OF 'DEPT_PK' (UNIQUE) (Cost=1 Card=1 Bytes=3)


SQL> create materialized view mv_test
enable query rewrite
as
select d.deptno, sum(e.sal) dept_tot
from emp e, dept d
where e.deptno=d.deptno
group by d.deptno;

Materialized view created.


SQL> select d.deptno, sum(e.sal) dept_tot
from emp e, dept d
where e.deptno=d.deptno
group by d.deptno;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=41 Bytes=1066)
   1    0   TABLE ACCESS (FULL) OF 'MV_TEST' (Cost=3 Card=41 Bytes=1066)


SQL> select sum(e.sal) dept_tot
from emp e, dept d
where e.deptno=d.deptno and e.deptno=10;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=1 Bytes=26)
   1    0   SORT (AGGREGATE)
   2    1     TABLE ACCESS (FULL) OF 'MV_TEST' (Cost=3 Card=1 Bytes=26)


SQL> select * from mv_test;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (FULL) OF 'MV_TEST'


<< Materialized view drop >>
SQL> drop materialized view mv_test


1) 테이블 삭제시 같은 mview 이름이 dba_tables에 있으면 안됨
note 148379.1 , 265455.1 Drop Materialized View Gives ORA-12083 and ORA-04020
Problem Description
-------------------
When you issue the following command to drop a table, you receive an ORA-12083,
indicating that there is a materialized view. For example:


SQL> drop table account_ref_x;
drop table account_ref_x
*
ERROR at line 1:
ORA-12083: must use DROP MATERIALIZED VIEW to drop "DTMADMIN"."ACCOUNT_REF_X"

If you try to drop the materialized view, the error that the snapshot does not
exist is returned:


SQL> DROP MATERIALIZED VIEW account_ref_x;
DROP MATERIALIZED VIEW account_ref_x
*
ERROR at line1:
ORA-12003: snapshot "DTMADMIN"."ACCOUNT_REF_X" does not exist


2) 해당 mview에 second materilized view가 있으면 안됨
note 174048.1 OERR: ORA-32300 cannot drop a secondary materialized view %s . %s
Drop the materialized view that contains the nested table column.
This will implicitly drop all secondary materialized views.


3) drop하고자하는 유저에 권한으로 error
note 215462.1 Dropping a Materialized View Log in a different schema fails
with error ORA-01031

You should confirm that user who drops the Materialized view log (snapshot log)
on different schema has the following rights

Drop Any Snapshot (Drop Any Materialized View)
Drop Any Table


4) refrech complete가 되어 있지 않으면 에러
note 221775.1
ORA-00955 When Dropping Materialized View Which Does Not Exist In Data Dictionary Views


5) 그런데.. mview를 count할 때에 drop도 가능하고, base테이블에 트랜잭션이
있어도 mview는 삭제가 되네요...

SQL> alter table dept add constraints con_dept_pk primary key (deptno);

SQL> alter table emp add constraints con_emp_fk
foreign key (deptno) references dept;


SQL> create materialized view mv_dept
tablespace users
build immediate
refresh on commit
enable query rewrite
as select e.empno, e.ename, d.dname from emp e, dept d
where e.deptno=d.deptno;


SQL> insert into dept values (50,'kkk','kkk');
1 row created.

SQL> commit;
Commit complete.


SQL> insert into emp(empno,ename, deptno) values (1234,'KKK',50);
1 row created.


SQL> COMMIT;
Commit complete.


SQL> select * from mv_dept;
EMPNO ENAME DNAME
---------- ---------- --------------
7369 SMITH RESEARCH
7499 ALLEN SALES
7521 WARD SALES
7566 JONES RESEARCH
7654 MARTIN SALES
7698 BLAKE SALES
7782 CLARK ACCOUNTING
7788 SCOTT RESEARCH
7839 KING ACCOUNTING
7844 TURNER SALES
7876 ADAMS RESEARCH

EMPNO ENAME DNAME
---------- ---------- --------------
7900 JAMES SALES
7902 FORD RESEARCH
7934 MILLER ACCOUNTING
1234 KKK kkk

15 rows selected.


그렇다면 YYY를 넣는 세션에 트랜잭션을 일으키고 COMMIT을 안함


SQL> insert into dept values (60,'YYY','YYY');
1 row created.

SQL> commit;
SQL> insert into emp(empno,ename, deptno) values (2345,'YYYY',60);
1 row created.

이 상태에서 mview를 drop하려함


SQL> drop materialized view mv_dept;
Materialized view dropped.


즉 base table에 트랜잭션이 있어도 삭제 가능
그러면 mview에 대해서 select하는 중에 삭제 가능?


- 다른 세션에서 수행
SQL> select count(*) from mv_dept, mv_dept, mv_dept, mv_dept, mv_dept, mv_dept;

- 이후 바로 삭제를 하였음.. prompt가 떨어짐..


SQL> drop materialized view mv_dept;

Materialized view dropped.

- 잠시 시간이 지난 후 다른 세션에서 조회하던 결과값이 도출

COUNT(*)
----------
11390625



참고자료 : http://blog.naver.com/ewnho?Redirect=Log&logNo=20012738376

크리에이티브 커먼즈 라이센스
Creative Commons License
2008/01/16 14:14 2008/01/16 14:14
Posted by

Leave your greetings.

  1. A contented mind is the greatest blessing a man can enjoy in this world Retro Jordan 6.If you would know the value of money,go and try to borrow some Replica Chanel Watches.Sometimes one pays most for the things one gets for nothing True Religion Outlet.You have to believe in yourself.That's the secret of success Juicy Couture Swimwear.Our destiny offers not the cup of despair,but the chalice of opportunity Juicy Couture Laptop Case .Genius only means hard-working all one's life Air Jordan 6.You can tell the ideals of a nation by its advertisements Retro 6.The only limit to our realization of tomorrow will be our doubts of today Cheap True Religion Jeans.The man with a new idea is a crank until the idea succeeds Cheap Chanel Handbags.The important thing in life is to have a great aim,and the determination to attain it Retro 3 Jordan.If you doubt yourself,then indeed you stand on shaky ground Air Yeezy 2.

    2012/04/19 17:04 [ Permalink : Modify/Delete : Reply ]

DATABASE/Oracle2007/08/27 21:13
by Oracle® Database Reference
CLUSTERING_FACTOR NUMBER Indicates the amount of order of the rows in the table based on the values of the index.
  • If the value is near the number of blocks, then the table is very well ordered. In this case, the index entries in a single leaf block tend to point to rows in the same data blocks.

  • If the value is near the number of rows, then the table is very randomly ordered. In this case, it is unlikely that index entries in the same leaf block point to rows in the same data blocks.



분리형 데이블의 구조가 가지는 최대의 특징은 바로 데이터의 값에 전혀 무관하게 '임의의 위치'에 저장된다는 것이다. 이는 우리가 원하는 값을 찾으려면 필연적으로 여러곳을 찾아보야야 한다는 것을 의미한다.
여기서 논리적 용어인 '임의의 위치'라는 의미를 다른뜻으로 해석해 보면 물리적으로 위치할 수 있는 방법은 너무 다양할 수 있음을 뜻한다. 즉, 아무 곳에 있어도 된다는 뜻은 곧 그들이 있어야 할 위치가 다양한 블록에 흩어져 있을 수 있음을 의미한다.
그렇다면 그들이 흩어져 있는 정도에 따라, 다시 말해서 찾고자 하는 값들이 얼마나 가까운 위치에 모여 있느냐의 정도에 따라 차이가 발생할 수 있다. 가령 1부터 10까지의 데이터가 10개의 블록에 흩어져 저장되어 있는 경우와 2개의 블록에 모여 있는 경우를 비교했을 때 비록 논리적인 액세스 건수는 동일하지만 물리적 액세스에는 5배의 차이가 난다.
관계형 데이터베이스에서는 어떠한 경우에라도 최소한 하나의 블록은 액세스 되어야 한다.
비록 우리는 로우를 액세스하지만 실제로는 블록이 액세스된다. 그러므로 만약 이미 액세스해 두었던 블록에서 원하는 로우를 찾을 확률이 높다면 물리적으로 액세스할 블록의 수는 분명히 줄어들 것이다.

시스템 환경에 따라 차이는 있겠지만 일반적으로 메모리에 있는 블록에서 원하는 데이터를 찾는 것과 디스크에 있는 블록에서 찾는 것은 30배 이상 차이가 날 수도 있다. 그렇다면 설사 임의의 위치에 흩어져 있더라도 얼마나 주변에 모여 있느냐에 따라 액세스 효율은 커다란 영향을 받게될 것이다.
물리적인 저장 방법이란 저장할 때 결정되는, 단 한가지의 형태로만 존재할 수 있는 것이기 때문에 액세스 조건에 따라 마음대로 저장을 다르게 할 수는 없다. 그러므로 액세스할 컬럼에 따라 현재 저장된 형태와의 모여이쓴 정도에는 차이가 날 수 밖에 없다. 이것은 마치 같은 형제들이지만 부모와 닮아 있는 정도는 차이가 있는 것과 유사하다고 할 수 있다.
이처럼 인덱스의 컬럼값으로 정렬되어 있는 인덱스 로우의 순서와 테이블에 저장되어 있는 데이터 로우의 위치가 얼마나 비슷한 순서로 저장되어 있느냐에 대한 정도를 나타내는 것을클러스터링 팩터(Clustering Factor)라고 한다.
클러스터링 팩터를 향상시키는 것은 이처럼 액세스 효율에 직접적인 영향을 미치기 때문에 모든 유형의 테이블의 구조에서도 항상 이 문제로 촉각을 곤두 세우게 된다.

인덱스는 인덱스컬럼과 ROWID로 정렬되어 있다. 물론 생성 시의 옵션에 따라 오름차순(Ascending)으로 정렬될 수도, 내림차순(Descending)으로 정렬될 수도 있다. 이러한 구조가 가지는 특징은 많은 액세스적인 특징과 밀접한 관련이 있다. 이 말은 곧 이러한 정렬을 하는것은 나름대로 매우 합리적인 이유를 가지고 있다는 것을 의미한다.
인덱스가 로우를 액세스하는 경우를 분석해 보면 블록별로 액세스가 발생하고, 같은 블록 내에 있는 로우의 위치는 순서를 지키고 있지 않다. ROWID로 정렬되었다는 것은 곧 물리적인 데이터 파일의 블록으로 정렬되고, 거기에서 다시 슬롯번호로 정렬되었다는 것을 뜻한다.
이처럼 블록으로 정렬되어 있기 때문에, 블록별로 액세스가 일어날 때 한 번의 블록 액세스로 최대한 많은 로우를 액세스 할 수 있데 한다는 것은 알 수가 있다. 비록 실제의 로우는 순서대로 저장되어 있지 않더라도 슬롯에 들어 있는 위치정보를 이용하면 언제라도 원하는 로우를 찾을 수 있다. 이것은 인덱스에 있는 ROWID의 정렬이 단지 슬롯번호의 정렬에 지나지 않지만 로우를 액세스 하는 데는 전혀 문제가 없음을 의미한다. 
클러스터링 팩터가 좋은 인덱스로 액세스를 하면 많은 로우를 액세스 하더라도 보다 적은 블록을 액세스 하게 되어 더 효율적일 수 있다. 이것은 이왕이면 자주 넓은 범위를 액세스해야 하는 경우에 유리하도록 저장을 해 두는 것이 무척 중요하다는 것을 의미한다.

빈번하게 넓은 범위를 액세스하는 순서로 데이터를 저장함으로써 클러스터링 팩터를 향상시키는 전략에는 여라가지가 있다.
저장 시의 과도한 비용을 감수하고라도 원하는 형태의 액세스를 위해 클러스터링 팩터를 높여주는 좀더 적극적인 방법들이 다양하게 있다. 가장 소극적인 방법은 지금 설명하고 있는 분리형의 구조처럼 저장형식에 강제적인 제약없이 임의의 위치에 저장하는 방식이다.
크리에이티브 커먼즈 라이센스
Creative Commons License
2007/08/27 21:13 2007/08/27 21:13
Posted by
Tags ,

Leave your greetings.