728x90
# I/O EVENT
l Direct path I/O 가 발생하는 경우
1. 정렬작업
2. prallel 힌트를 쓴 쿼리문
3. parallel 힌트를 쓴 dml 문
4. insert /*+ append *? into 테이블명
5. SQL*Loader 사용시
- $sqlldr scott/tiger control=control01.ctl direct = y
l Buffer cache를 통과하는 Conventional path I/O 일때 발생하는 이벤트
1. db file sequential read
- index를 넓게 읽으면서 테이블을 엑세스 할 때 발생
- 해결 방법 - index를 넓게 읽지 않도록 해야 한다
: SQL 튜닝
: 인덱스 재구성
2. db file scattered read
- full table scan을 할 때
select ename, sal, job, deptno from emp where deptno in (10,20,30); | select ename, sal, job, deptno from emp where deptno = 10; |
select ename, sal, job, deptno from emp where deptno = 20; | |
select ename, sal, job, deptno from emp where deptno = 30; | |
select /*+ full(emp) parellel(emp,4) */ ename, sal, job, deptno from emp where deptno in (10,20,30); - 위 쿼리는 결국엔 위처럼 3가지 쿼리로 나눠서 실행된다 - 위 쿼리는 deptno에 인덱스가 달려있다면 대부분의 데이터를 index로 넓게 읽고있다 - 이러면 conventional I/O 이벤트가 자주 발생한다 - 그렇기 때문에 차라리 full table scan을 튜닝하는 것이 낫다고 볼 수 있다 - 이런 경우 clustoring factor가 높아지기 때문에 개선이 필요하다 |
l Clustering Factor
l where job = ‘SALESMAN’ 이라고 작성했는데 인덱스를 넓게 읽을 수 밖에 없는 경우가 있다
- 이것은 인덱스의 클러스터링 팩터가 안좋기 떄문이다
- clustering factor를 해결하기 위해서는 index는 이미 ascending 하게 정렬되어있기 때문에 block들의 데이터들도 정렬해서 배치되야 한다
- index를 스캔하는데 한 블록에 row 4개가 전부있을 때는 CF가 1로써 낮아지고index 스캔한는데 각각 다른 블록에 row가 4개가 있다면 CF가 4로 높아진다
l Clustering Factor 가 좋은경우
- 왼쪽에 인덱스고 오른쪽이 block 이라면 왼쪽에서 1~3번을 스캔하는데 해당하는 block이 한 곳에 몰려있으면 속도가 빠르다
l Clustering Factor가 안좋은 경우
- 하지만 위처럼 중구난방으로 다른 block에 들어있다면 속도가 느리다
n Clustering factor 해결방법
SQL> SELECT index_name, clustering_factor FROM dba_indexes WHERE owner='OWI'; INDEX_NAME CLUSTERING_FACTOR ------------------------------ ----------------- SYS_C0011387 SYS_C0011388 SYS_C0011389 SYS_FK0000088870N00012$ 0 SYS_FK0000088870N00014$ 0 IDX_CACHE_BUFFERS_CHAINS 7276 IDX_DB_FILE_SEQUENTIAL_READ 1606364 SQL> SELECT COUNT(*) FROM owi.T_DB_FILE_SEQUENTIAL_READ; COUNT(*) ---------- 1600000 - 테이블의 건수보다 clustering factor 가 더 크면 좋지 않다는 의미이다 >> DB file sequential read 대기 이벤트를 일으키고 snapshot을 찍어서 AWR compare report로 결과를 확인 SQL> exec dbms_workload_repository.create_snapshot; SQL> @exec db sequential read 발생하는 것을 확인할 수 있고 하단에 index에 의한 쿼리가 발생했다는 것을 알 수 있다 >> DB sequential read를 줄이기 위해서 block을 순서대로 정렬해서 다시 테이블을 생성하고 report 생성 SQL> SELECT * FROM dba_ind_columns WHERE index_name = 'IDX_DB_FILE_SEQUENTIAL_READ'; - 어떤 column에 index가 걸려있는지 확인해보면 id에 인덱스가 걸린 것을 확인할 수 있다 SQL> CREATE TABLE t_db_file_sequential_read2 AS SELECT * FROM t_db_file_sequential_read ORDER BY id asc; - db sequential read 이벤트를 발생시키는 테이블을 백업 - 중요한 것은 ascending 하게 정렬해줘야 한다 SQL> DROP TABLE t_db_file_sequential_read; SQL> RENAME t_db_file_sequential_read2 TO t_db_file_sequential_read; - 본래 테이블을 삭제하고 백업한 테이블을 원래 이름으로 생성한다 SQL> CREATE INDEX idx_db_file_sequential_read ON t_db_file_sequential_read(id); - 테이블이 drop 됐기 때문에 id 컬럼에 index 역시 다시 생성해야 한다 SQL> @?/rdbms/admin/awrddrpt.sql SQL> exec dbms_workload_repository.create_snapshot; SQL> @exec SQL> exec dbms_workload_repository.create_snapshot; - DB file sequential read가 줄어든 것을 확인 할 수 있다 |
'빅데이터과정 > OWI' 카테고리의 다른 글
#42_140811_OWI_REDO LOG BUFFER (0) | 2014.08.11 |
---|---|
#44_140811_OWI_LOCK (0) | 2014.08.11 |
#41_140808_OWI_DB BUFFER CACHE (0) | 2014.08.08 |
#40_140807_OWI_ROW CACHE LOCK (0) | 2014.08.07 |
#40_140807_OWI_ENQUEUE (0) | 2014.08.07 |