Table Full Scan
- 테이블에 속한 블록 전체를 읽어서 사용자가 원하는 데이터를 찾음
- 시퀀셜 액세스 + Multi Block I/O
- Table Full Scan는 피해야 한다는 인식이 많지만, 오히려 인덱스를 사용하는 것이 성능을 떨어뜨리는 경우가 더 많음
- 캐시에서 못 찾으면 한 번의 I/O Call로 인접한 수십-수백 개의 블록을 한꺼번에 불러오는 것이 좋음
Index Range Scan
- 인덱스 선두 컬럼이 가공되지 않은 상태로 조건절에 있어야 Index Range Scan이 가능
- 인덱스에서 일정량을 스캔하면서 얻은 ROWID로 테이블 레코드를 찾음
- 시퀀셜 액세스 + Multi Block I/O가 좋아도 소량의 데이터를 찾을 때 테이블 전체를 스캔하는 것은 비효율적임, 큰 테이블에서 소량의 데이터를 찾을 때는 반드시 인덱스를 사용해야 함
- 랜덤 액세스 + Single Block I/O
- 캐시에서 못 찾으면 레코드 하나를 읽기 위해 매번 I/O Call이 필요, 그러므로 많은 데이터를 읽을 때는 Table Full Scan보다 불리함
- 인덱스는 큰 테이블에서 아주 적은 일부의 데이터를 빨리 찾기 위한 도구일 뿐, 읽을 데이터가 일정 수량을 넘으면 인덱스보다는 Table Full Scan을 사용하는 것이 유리
- 인덱스를 안 타서 느린 경우보다 불필요하게 인덱스를 타서 느린 경우가 더 많더라...
- 예상 카디널리티가 일정량을 넘는 경우 인덱스 스캔을 하지 말도록... 힌트를 사용하여 Table Full Scan을 유도
Indes Full Scan
- 인덱스 선두 컬럼이 조건절에 없으면, Index Range Scan을 불가능하므로, 옵티마이저는 Table Full Scan을 고려함
- 그런데, 대용량 테이블이라 Table Full Scan에 대한 부담이 너무 크면, Index를 활용해야 할 필요가 있음
- 인덱스의 전체 크기는 테이블의 전체 크기보다 훨씬 적으므로, Index Range Scan을 할 수 없을 때, Table Full Scan보다는 Index Full Scan을 하는 것이 좋을 수 있음
- Index Scan을 통해 대부분의 레코드를 필터링하고 아주 일부만 테이블 액세스하는 상황이라면 크기가 큰 테이블을 Table Full Scan을 하기보다는 Index Full Scan 하는 것이 유리함
SELECT *
FROM EMP
WHERE SAL > 9000
ORDER BY ENAME;
- 조건절 선두에 인덱스 선두 컬럼인 ENAME이 없어서 Index Range Scan은 불가능
- SAL > 9000인 레코드가 전체 테이블에서 아주 작은 일부라면 Table Full Scan보다는 Index Full Scan이 유리
- 하지만 이러한 Index Full Scan은 Index Range Scan을 하지 못한 차선책이므로, 수행 빈도가 낮은 SQL이라면 상관없지만, 그렇지 않다면 SAL칼럼이 인덱스 선두 컬럼인 인덱스를 생성하는 것이 좋음
'DATABASE > 튜닝' 카테고리의 다른 글
[SQL 튜닝] 인덱스 기본 사용법 (0) | 2020.06.15 |
---|---|
[SQL 튜닝] 인덱스 구조 및 탐색 (0) | 2020.06.15 |
[SQL 튜닝] 데이터베이스 저장 구조와 I/O 메커니즘 (0) | 2020.06.07 |
[SQL 튜닝] SQL 공유 및 재사용(라이브러리 캐시, SQL캐싱) (0) | 2020.06.07 |
[SQL 튜닝] SQL 파싱과 최적화 (0) | 2020.06.07 |