Recent Posts
간단명료
인덱스 활용이 불가능한 경우 본문
1. 인덱스를 사용하지 말아야 하는 경우
분포도가 좋지 않을 경우 FULL TABLE SCAN이 더 나을 수 있다.
처리 데이터가 전체 데이터 중 15% 이상일 경우 FULL SCAN이 더 나을 수 있다.
2. 인덱스 사용이 불가능한 경우
1) NOT 연산자 사용
!=
, <>
: 제외한 모든 데이터를 추출하기 때문에 인덱스보다 FULL TABLE SCAN이 더 나을 수 있다.
2) IS NULL, IS NOT NULL 사용
인덱스는 NULL 값을 저장하지 않는다.
3) 옵티마이저의 취사 선택
- RBO : 정해진 규칙 기준
- CBO : 비용 기준
- 으로 취사 선택. Hint를 통해 제어할 수 있다.
4) External suppressing - 인덱스 컬럼 변형
불필요한 함수 사용
WHERE SUBSTR(ename,1,1) = 'M'; -- 컬럼 변형으로 인해 인덱스 사용 불가 _______아래와 같이 수정_______ WHERE ename LIKE 'M%'; -- 인덱스 사용 가능
문자열 결합
WHERE job||deptno = 'MANAGER10'; -- 컬럼 변형으로 인해 인덱스 사용 불가 _______아래와 같이 수정_______ WHERE job = 'MANAGER' AND deptno = 10; -- 인덱스 사용 가능
DATE 변수의 가공
WHERE TO_CHAR(hiredate,'YYYYMMDD') = '20220326'; -- 컬럼 변형으로 인해 인덱스 사용 불가 _______아래와 같이 수정_______ WHERE hiredate BETWEEN TO_DATE('20220326','YYYYMMDD') AND TO_DATE('20220326','YYYYMMDD')
산술식의 적용
WHERE sal*12 > 40000; -- 컬럼 변형으로 인해 인덱스 사용 불가 _______아래와 같이 수정_______ WHERE sal > 40000/12; -- 인덱스 사용 가능
5) Internal suppressing - 인덱스 컬럼 변형(데이터 내부)
VARCHAR2 or CHAR -> NUMBER : 연산 시 NUMBER 타입으로 형 변환이 이뤄진다.
comm + '500' bonus > sal/'10' -- 논리비교 연산식 MOD (sal, '100') -- 함수호출
VARCHAR2 or CHAR to DATE : 연산 시 DATE 타입으로 형 변환이 이뤄진다.
WHERE hiredate = '2022-03-16' WHERE ROWID = 'AAAAaoAATAAAAADAAA'; -- ROWID 타입으로 형변환 이뤄짐
형변환으로 인한 인덱스 사용 불가
WHERE resno = 740211215156 -- resno : VARCHAR2 타입 주민번호 (=) 연산 시 아래와 같다 WHERE TO_NUMBER(resno) = 740211215156 -- 컬럼 타입 변환이 되기 때문에 인덱스 사용 불가(Full Scan)
3. 옵티마이저에 의한 선택 절차
1) 주어진 조건에 대한 각 인덱스 별로 매칭률을 계산해서 "매칭률이 높은 것" 을 우선적으로 선택
인덱스매칭률
= WHERE절에서1st 컬럼 부터 연속된 컬럼에 대해 상수(값)를 '='로 비교하는 컬럼 갯수 / 인덱스를 구성하는 컬럼의 총 갯수
2) 인덱스 별 매칭률이 같을 경우, 인덱스를 구성하는 "컬럼의 갯수가 많은 것"을 우선적으로 선택
3) 인덱스 별 매칭률과 인덱스를 구성하는 컬럼의 갯수가 같을 경우, "가장 최근에 생성된 것"을 우선적으로 선택

->인덱스 변경 후, 인덱스 매칭률이 바뀌기 때문에 IX2_SALES
인덱스를 선택하게 된다.
-
-
출처 : EZ Learning - [업무에 바로 쓰는 SQL튜닝 입문] 강의
728x90
반응형
'SQL > 업무에 바로 쓰는 SQL튜닝 입문' 카테고리의 다른 글
NL(Nested Loops) 조인 (0) | 2022.03.31 |
---|---|
서브쿼리 (0) | 2022.03.28 |
결합인덱스 (0) | 2022.03.26 |
인덱스 (0) | 2022.03.26 |
옵티마이저 (0) | 2022.03.26 |