이전글에서는 외부쿼리에서 View안으로 조건을 침투해서 사용하는 방법에 대해 정리했습니다.
2023.07.12 - [DB/오라클] - View 조건침투(condition Pushdown)
이번에는 View안으로 Hint를 침투하는 방법에 대해 포스팅해보겠습니다.
View에서 Hint사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
--Local Hint Example
--VIEW===========================
CREATE VIEW ActiveEmployees
AS
SELECT /*+ FULL(E)*/
E.EMP_NO
,E.NAME
,E.AGE
FROM Employees E
WHERE E.IsActive = 'Y' ;
--Query==========================
SELECT *
FROM ActiveEmployees A
,DEPT D
WHERE A.DEPTNO = D.DEPTNO
;
|
cs |
위의 예제쿼리는 View안에 Employees 테이블을 FullScan 하도록
내부에서 Hint를 사용하고 있는데 이것을 Local Hint라고 부릅니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
--Global Hint Example
--VIEW===========================
CREATE VIEW ActiveEmployees
AS
SELECT E.EMP_NO
,E.NAME
,E.AGE
FROM Employees E
WHERE E.IsActive = 'Y' ;
--Query==========================
SELECT /*+ FULL(A.E)*/
*
FROM ActiveEmployees A
,DEPT D
WHERE A.DEPTNO = D.DEPTNO
;
|
cs |
두 번째 예제쿼리에서는 View내부가 아닌 View를 호출해서 사용하는 외부쿼리에 Hint를 걸고 있습니다.
이러한 방식을 Global Hint라고 합니다.
View는 가급적 Local Hint 사용을 지양해야 합니다.
이유는 옵티마이저가 효율적인 실행계획을 만들어서 데이터를 가져오려고 해도
View내부에서 Local Hint가 존재한다면 그 힌트에 맞는 AcessPath를 더 우선순위로 가져가기 때문입니다.
Global Hint 사용 시 주의사항
- Inline View, View에는 반드시 Alias를 주어 연결고리를 만들어야 합니다.
Global Hint는 View의 이름 또는 Alias로 침투시키기 때문에 침투를 위한 연결고리 역할을 합니다.
1
2
3
4
5
6
7
8
9
10
11
|
--Bad Example
SELECT /*+ FULL(A.SUBE)*/
*
FROM (
SELECT *
FROM Employees
WHERE IsActive = 'Y'
) A, DEPT D
WHERE A.DEPTNO = D.DEPTNO
;
|
cs |
위의 예제를 보면 Inline View안에 Alias가 없습니다.
이로 인해 Global Hint에서 FULL(A.SUBE) 힌트를 주어 FULL Scan을 유도했지만 무시당하고 Range Scan을 하게 됩니다.
"명심하자! Alias가 Hint를 침투시키기 위한 징검다리 역할을 한다"
- UNION ALL 사용 시 Inline View, View, 테이블 Alias를 모두 다르게 주어 연결고리를 만들어야 합니다.
UNION ALL로 여러 쿼리가 묶여 있을 때 글로벌 힌트를 VIEW안에 잘 침투시키기 위해 Alias를 사용하는 방법입니다.
Global Hint를 View안에 침투심킬 때는
Alias.Alias... 과 같이 Alias로 밖에 침투를 못 시킵니다.
그렇기 때문에 UNION ALL 로 묶인 쿼리에 각각 다른 Alias를 주어서 각각 힌트를 사용할 수 있도록 해야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
--UNION ALL Example
SELECT /* FULL(INLINE_VIEW.EMP_V_1)
FULL(INLINE_VIEW.EMP_V_2)
FULL(INLINE_VIEW.EMP_V_3)
*/
*
FROM DEPT D,
(SELECT EMP_V_1.*
FROM EMP EMP_V_1
UNION ALL
SELECT EMP_V_2.*
FROM EMP EMP_V_2
UNION ALL
SELECT EMP_V_3.*
FROM EMP EMP_V_3
) INLINE_VIEW
WHERE D.DEPNO = INLINE_VIEW.DEPNO
;
|
cs |
정리
View를 사용시 가급적 Local Hint를 지양한다.
Alias가 연결다리 역할을 하기 때문에 View안에 Alias를 잘 설계해야한다.
UNION ALL을 사용시 각각의 쿼리에 다른 Alias로 정의하여 외부쿼리에서 각각 HINT를 사용한다.
읽어주셔서 감사합니다.
