탑크리에듀(www.topcredu.co.kr),오라클자바커뮤니티(http://ojc.asia) 제공 오라클/SQL힌트 및 튜닝 강좌 입니다. 오라클 구체화뷰(Materialized Views)는 그룹함수 튜닝의 용도로 만들어지는 실제 데이터를 Table Segment에 저장하고 있는 뷰 입니다. 오라클 옵티마이저는 사용자의 쿼리가 Mview를 통해 다시 작성할 수 있을 때 Mview를 사용하지 않은 쿼리보다 비용이 적다고 판단이 될 때 쿼리 변환을 시도하며 비용기반 옵티마이저(Cost Based Optimizer)에서 가능합니다. 즉 옵티마이저 모드가 ALL_ROWS, FIRST_ROWS, FIRST_ROWS_n이 되어야 하며
만약 비용과 관계없이 Mview를 사용하고 싶다면 REWRITE 힌트를 사용하면 됩니다.
3. Query Rewrite with Materialized Views
• 구체화뷰(Materialized Views)는 그룹함수 튜닝의 용도로 만들어지는 실제 데이터를
Table Segment에 저장하고 있는 뷰이다.
• 오라클 옵티마이저는 사용자의 쿼리가 Mview를 통해 다시 작성할 수 있을 때 Mview를
사용하지 않은 쿼리보다 비용이 적다고 판단이 될 때 쿼리 변환을 시도하며 비용기반 옵
티마이저(Cost Based Optimizer)에서 가능하다. 즉 옵티마이저 모드가 ALL_ROWS,
FIRST_ROWS, FIRST_ROWS_n이 되어야 한다.
• 만약 비용과 관계없이 Mview를 사용하고 싶다면 REWRITE 힌트를 사용하면 되고 특별히
사용하지 않으려면 NOREWRITE 힌트를 사용하면 된다.
이종철, 탑크리에듀(www.topcredu.co.kr)
4. 구체화 뷰(Materialized Views) ?
• 구체화 뷰 (MATERIALIZED VIEW) 는 기존 뷰와 비슷하지만, 다른 점은 실제 데이터를 자
신이 가지고 있으며 원본 테이블에 INSERT, UPDATE, DELETE가 발생하면 새로운 데이터
를 즉시 또는 이후에 구체화된 뷰에 반영되도록 한다.
• 구체화 뷰의 용도 그룹함수 튜닝을 위해 주로 사용하는데, 그룹함수 min, max, sum,
avg 등의 값을 미리 만들어 놓을 때 유용하며 USER_MVIEWS, USER_SEGMENTS,
USER_OBJECTS에서 확인 가능하다.
• CBO에서 구체화뷰를 사용하기 위한 힌트는 REWRITE인데 힌트 구문에 구체화뷰가 인자
로 와도 되고 안 와도 되며 인자로 뷰 리스트를 주지 않는 경우 적절한 MATERIALIZED
VIEW를 찾고 항상 비용(COST)과 관계없이 사용 한다.
이종철, 탑크리에듀(www.topcredu.co.kr)
5. 구체화 뷰(Materialized Views) 기본 형식
• CREATE MATERIALIZED VIEW 뷰이름
• TABLESPACE 테이블스페이스이름
• BUILD [IMMEDIATE | DEFERRED] //immediate는 즉시 mview를 활성화
//deferred:다음 refresh 때 데이터가 채워짐
• REFRESH [FAST | COMPLETE | FORCE ]
• ON [COMMIT | DEMAND ]
• [[ENABLE | DISABLE] QUERY REWRITE]
• [ON PREBUILT TABLE]//create table as select…(CTAS)로 이미 테이블이 생성된 경우
• // 이를 query rewrite가 가능하도록 mview로 만드는 옵션
• AS SELECT ...;
이종철, 탑크리에듀(www.topcredu.co.kr)
6. 구체화 뷰(Materialized Views)를 위한 권한 - 1
• 구체화뷰를 만들고 관리하기 위해서는 스키마 계정에 몇가지 권한이 필요하다.
1. 자신의 스키마 계정에 Mview를 만들기 위해서는 아래의 권한이 필요하다.
CREATE MATERIALIZED VIEW system privilege.
CREATE TABLE or CREATE ANY TABLE system privilege.
SELECT ANY TABLE system privilege.
2. 다른 사용자 스키마에 Mview를 만들기 위해서는 다음과 같은 권한이 추가로 필요하다.
CREATE ANY MATERIALIZED VIEW system privilege.
SELECT ANY TABLE system privilege.
이종철, 탑크리에듀(www.topcredu.co.kr)
7. 구체화 뷰(Materialized Views)를 위한 권한 - 2
3. refresh-on-commit Mview를 만들기 위해서는 다음 권한이 추가로 필요하다.
ON COMMIT REFRESH system privilege.
4. Query rewrite enabled 형태로 Mview를 만들기 위해서는 다음권한이 추가로 필요하다.
GLOBAL QUERY REWRITE privilege or the QUERY REWRITE
5. On PREBUILT TABLE구로 Mview를 만들기 위해서는 다음 권한이 추가로 필요하다.
SELECT privilege WITH GRANT OPTION(Container Table에 대해)
6. 마스터 테이블 또는 Mview 인덱스를 특정 테이블스페이스에 대해 생성하기 위해서는
아래 권한이 추가로 필요하다.
UNLIMITED TABLESPACE system privilege.
이종철, 탑크리에듀(www.topcredu.co.kr)
8. Materialized Views 예제(부서별 최소급여) - 1
-- 부서별 최소급여를 구하는 쿼리 2.5초
-- Mview가 생성되지 않은 상태에서 아래 쿼리를 실행하자.부서별 급여최소값을
-- HASH GROUP BY로 구하는 과정때문에 시간이 걸린다.
SELECT deptno, empno, sal
FROM myemp1
WHERE (deptno, sal) in (SELECT deptno, MIN(sal)
FROM myemp1
GROUP BY deptno);
이종철, 탑크리에듀(www.topcredu.co.kr)
9. Materialized Views 예제(부서별 최소급여) - 2
-- 부서별 최소급여를 Mview를로 생성하자.
DROP MATERIALIZED VIEW M_DEPT_MINSAL ;
CREATE MATERIALIZED VIEW M_DEPT_MINSAL
BUILD IMMEDIATE -- MVIEW만들때 데이터 생성하라
REFRESH COMPLETE -- 갱신시 전부 갱신
ON DEMAND -- DBMS_MVIEW패키지에서 REFRESH명령시 또는주기마다 갱신
--1시간마다 갱신
START WITH SYSDATE NEXT SYSDATE + 1/24
ENABLE QUERY REWRITE
AS
SELECT deptno, MIN(sal) FROM myemp1 GROUP BY deptno ;
생성 후 통계정보 수집
BEGIN
DBMS_STATS.gather_table_stats(
ownname => 'SCOTT',
tabname => 'EMP_MV'); END;
/
이종철, 탑크리에듀(www.topcredu.co.kr)
10. Materialized Views 예제(부서별 최소급여) - 3
-- 0초, Mview를 사용한다.
SELECT deptno, empno, sal
FROM myemp1
WHERE (deptno, sal) in (SELECT deptno, min(sal)
FROM myemp1 GROUP BY deptno);
-- 테스트를 위해 데이터를 한건 생성하자.
delete from myemp1 where empno = 11111111;
insert into myemp1(empno, ename, sal, deptno) values (11111111, '이종철',
5999999, '1');
commit;
이종철, 탑크리에듀(www.topcredu.co.kr)
11. Materialized Views 예제(부서별 최소급여) - 4
-- Mview를 갱신하지 않아 옵티마이저가 Mview를 사용안한다.
SELECT deptno, empno, sal
FROM myemp1
WHERE (deptno, sal) in (SELECT deptno, min(sal) FROM myemp1 GROUP BY deptno);
-- 힌트를 사용해도 Mview를 갱신하지 않아 옵티마이저가 사용안한다.
SELECT /*+ REWRITE */ deptno, empno, sal
FROM myemp1
WHERE (deptno, sal) in (SELECT deptno, min(sal) FROM myemp1 GROUP BY deptno);
이종철, 탑크리에듀(www.topcredu.co.kr)
12. Materialized Views 예제(부서별 최소급여) - 4
-- Mview를 갱신하자.
EXEC dbms_mview.refresh('M_DEPT_MINSAL', method=>'C');
-- 이제는 Mview를 사용한다.
SELECT /*+ REWRITE */deptno, empno, sal
FROM myemp1
WHERE (deptno, sal) in (SELECT deptno, min(sal)
FROM myemp1
GROUP BY deptno);
이종철, 탑크리에듀(www.topcredu.co.kr)
13. Materialized Views 예제(COUNT 튜닝) - 1
-- REFRESH FAST ON COMMIT 사용하여 MVIEW를 만들고 COUNT 연산을 튜닝하자.
-- MUEMP1 테이블의 PK인덱스 이름은 PK_MYEMP1 이다.
-- 오라클11g의 경우 COUNT SQL문 실행시 INDEX FAST FULL SCAN을 하도록 되어 있다.
-- 약 0.2~0.3초쯤 걸렸다.(CBO에서 힌트를 안써도 INDEX FAST FULL SCAN 스캔한다.)
SELECT COUNT(empno) FROM myemp1 e;
이종철, 탑크리에듀(www.topcredu.co.kr)
14. Materialized Views 예제(COUNT 튜닝) - 2
-- mview를 이용하여 count(*) 튜닝을 해보자. 물론 원본데이터가 변경 되더라도
-- 즉시 mview에 반영이 되어 count가 증가되어야 한다.
DROP MATERIALIZED VIEW LOG ON myemp1;
CREATE MATERIALIZED VIEW LOG ON myemp1 WITH PRIMARY KEY, ROWID INCLUDING NEW VALUES;
-- MVIEW를 만들자.
DROP MATERIALIZED VIEW m_count;
CREATE MATERIALIZED VIEW m_count
BUILD IMMEDIATE -- MView 생성과 동시에 데이터들도 생성
REFRESH FAST -- 원본의변경된 데이터만 mview에 갱신
ON COMMIT -- Commit 이 일어날 때 뷰 Refresh
ENABLE QUERY REWRITE
AS SELECT COUNT(*) cnt FROM myemp1;
이종철, 탑크리에듀(www.topcredu.co.kr)
15. Materialized Views 예제(COUNT 튜닝) - 3
-- count를 해보자 0초 걸린다. mview가 사용됨을 실행계획을 통해 알 수 있다.
SELECT COUNT(empno) FROM myemp1 e;
(결과)10000002
-- myemp table에 데이터를 한건 입력하고 mview에 실시간으로 반영되는지 확인하자.
INSERT INTO myemp1 (empno, ename) VALUES (11111112, '이종철2');
COMMIT;
SELECT COUNT(empno) FROM myemp1 e;
(결과)10000003
이종철, 탑크리에듀(www.topcredu.co.kr)