제6장 실체화 뷰

내용 목차

6.1. 리프레시
6.1.1. 완전 리프레시
6.1.2. 빠른 리프레시
6.2. 질의 다시 쓰기
6.2.1. 동작 조건
6.2.2. 동작 방식
6.2.3. 비용 기반 최적화
6.3. 원격 저장소를 가진 실체화 뷰
6.3.1. 실체화 뷰 생성 사전 작업
6.3.2. 실체화 뷰 생성
6.3.3. 리프레시 및 저장소 테이블 조회
6.3.4. 제약 사항

본 장에서는 Tibero에서 제공하는 실체화 뷰를 사용하는 방법에 대해 기술한다.

마스터 테이블에 변경이 일어났을 때 이를 반영하도록 실체화 뷰를 갱신하는 동작을 리프레시라고 한다. 리프레시를 하면 실체화 뷰의 데이터는 질의의 결과와 일치된다. 리프레시는 실체화 뷰를 생성하는 조건에 따라 자동으로 수행될 수 있으며, DBMS_MVIEW 패키지의 REFRESH 함수를 이용하여 수동으로 수행할 수도 있다.

리프레시는 완전 리프레시와 빠른 리프레시가 있다.

빠른 리프레시는 마스터 테이블의 변경된 부분만을 실체화 뷰에 반영하는 방식이다. 완전 리프레시보다 빠르다.

일반적인 제약조건

빠른 리프레시를 사용하기 위한 제약조건은 다음과 같다. 실체화 뷰를 정의하는 질의는 다음의 제약조건을 만족해야 한다.

  • 실체화 뷰는 SYSDATE와 ROWNUM과 같이 반복할 수 없는 표현식을 포함하면 안 된다.

  • 실체화 뷰는 LONG 또는 LONG RAW 데이터 타입을 포함하면 안 된다.

  • SELECT 리스트에 부질의를 포함하면 안 된다.

  • SELECT 리스트에 분석 함수를 포함하면 안 된다.

  • HAVING 절에 부질의를 포함하면 안 된다.

  • ANY, ALL, NOT EXISTS를 포함하면 안 된다.

  • [START WITH] CONNECT BY 절을 포함하면 안 된다.

  • 서로 다른 원격에 있는 테이블을 포함하면 안 된다. 즉, 쿼리에 참가하는 모든 테이블은 같은 서버에 있어야 한다.

  • 원격 테이블이 포함된 경우 해당 서버가 Tibero일 경우만 된다.

  • UNION 등의 SET 연산자를 포함하면 안 된다.

  • REFRESH ON COMMIT 실체화 뷰를 정의한 질의는 원격 테이블을 포함하면 안 된다.

집합 함수를 포함한 제약조건

다음은 집합 함수를 포함한 제약조건에 대한 설명이다.

  • 빠른 리프레시의 일반적인 제약조건을 모두 포함한다.

  • 실체화 뷰의 모든 참조 테이블에는 실체화 뷰의 로그가 있어야 하며, 실체화 뷰의 로그는 다음의 제약조건을 만족해야 한다.

    • 실체화 뷰에서 참조하는 모든 컬럼을 포함해야 한다.

    • SEQUENCE, ROWID와 INCLUDING NEW VALUES 조건이 있어야 한다.

  • 함수는 SUM, COUNT, AVG, STDDEV, VARIANCE. MIN, MAX 함수만 지원된다.

  • COUNT(*)는 항상 포함해야 한다.

  • 집합 함수는 항상 표현식의 최상위에 있어야 한다. 단, AVG(COUNT(X)), COUNT(X) * COUNT(X)는 허용하지 않는다.

  • AVG(expr)에 대응되는 COUNT(expr)가 있어야 한다.

    집단 함수필요 집단 함수
    COUNT(expr)-
    MIN(expr)-
    MAX(expr)-
    SUM(expr)COUNT(expr)
    SUM(col), col에 NOT NULL 제약-
    AVG(expr)COUNT(expr)
    STDDEV(expr)SUM(expr), COUNT(expr)
    VARIANCE(expr)SUM(expr), COUNT(expr)
  • SELECT 리스트에는 모든 GROUP BY 컬럼이 있어야 한다.

  • CUBE, ROLLUP은 허용하지 않는다.

실체화 뷰의 가장 큰 장점은 질의 다시 쓰기(Query Rewrite) 기능을 사용할 수 있다는 것이다.

질의 다시 쓰기는 주어진 질의를 분석한 후 실체화 뷰를 사용하여 동일한 결과를 내는 새로운 질의를 생성하는 기능이다. 실체화 뷰가 복잡한 조인이나 집단 함수의 결과로 정의되어 있다면 질의 다시 쓰기를 통해 실행 시간을 크게 단축할 수 있다.

질의 다시 쓰기는 사용자가 명시한 명령 없이도 질의 최적화기에 의해 수행되므로 실체화 뷰를 인덱스처럼 사용할 수 있다. INSERT, DELETE, UPDATE, MERGE의 대상이 되는 부질의를 제외한 모든 SELECT 문에 동작한다.

참고

EXPLAIN PLAN 문을 통해서 실행 계획을 보면 질의 다시 쓰기에 의해 참조된 실체화 뷰는 MV_REWRITE라고 표시된다.

질의 다시 쓰기를 하려면 원본 질의와 사용할 실체화 뷰의 질의를 비교해서 원본 질의가 실체화 뷰를 사용해서 얻어질 수 있는지를 확인해야 한다. 현재는 완전 문자열 비교와 부분 문자열 비교 방식을 지원한다.

완전 문자열 비교

원본 질의와 사용할 실체화 뷰의 질의에 대해 전체 문자열을 비교한다. 이때 공백이나 대소문자의 차이는 무시된다.

예를 들어 다음과 같은 실체화 뷰가 있다고 가정해 보자.

CREATE MATERIALIZED VIEW MV_SUM_SALARY ENABLE QUERY REWRITE AS
    SELECT DNAME, SUM(SALARY) FROM DEPT, EMP WHERE DEPT.DEPTNO = EMP.DEPTNO 
    GROUP BY DNAME;
  1. 다음과 같은 질의를 실행한다면,

    SELECT dname, SUM(salary) FROM dept,emp WHERE DEPT.DEPTNO = EMP.DEPTNO 
        GROUP BY dname;
  2. 다음과 같이 질의 다시 쓰기가 동작하게 된다.

    SELECT * FROM MV_SUM_SALARY;

부분 문자열 비교

원본 질의와 사용할 실체화 뷰의 질의에 대해 FROM 절부터 ORDER BY 절 앞까지(존재할 경우)의 문자열을 비교하고, SELECT 리스트와 ORDER BY 절의 연산식에서 사용되는 컬럼의 적합성을 조사한다.

컬럼의 적합성을 조사하는 방법은 다음과 같다.

원본 질의의 SELECT 리스트 컬럼이 실체화 뷰의 컬럼을 조합해서 얻어질 수 있는지를 검사한다. 이때 조인에 의해 같아지는 컬럼을 처리한다.

예를 들어 다음과 같은 실체화 뷰가 있다고 가정해 보자.

CREATE MATERIALIZED VIEW MV_JOIN_DEPT_EMP ENABLE QUERY REWRITE AS
    SELECT ENAME, DNAME, DEPT.DEPTNO FROM DEPT, EMP WHERE DEPT.DEPTNO = EMP.DEPTNO;
  1. 다음과 같은 질의를 실행한다면,

    SELECT ENAME, DNAME, EMP.DEPTNO FROM DEPT, EMP WHERE DEPT.DEPTNO = EMP.DEPTNO;
  2. 다음과 같이 질의 다시 쓰기가 동작하게 된다.

    SELECT ENAME, DNAME, DEPTNO FROM MV_JOIN_DEPT_EMP;

또한, 연산의 교환, 결합, 분배 법칙을 이용하여 동등한 연산식의 컬럼을 처리한다.

예를 들어 다음과 같은 실체화 뷰가 있다고 가정해 보자.

CREATE MATERIALIZED VIEW mymv ENABLE QUERY REWRITE AS
    SELECT a*(c+4)+b c1, sum(c+a)+1 c2 FROM base GROUP BY a*(c+4)+b, b+4*a+a*c;
  1. 다음과 같은 질의를 실행한다면,

    SELECT b+4*a+a*c+(1+sum(a+c))*7 FROM base GROUP BY a*(c+4)+b, b+4*a+a*c;
  2. 다음과 같이 질의 다시 쓰기가 동작하게 된다.

    SELECT c1+c2*7 FROM mymv;

집단 함수를 사용할 때 집단 함수의 적합성을 조사하는 방법은 다음과 같다.

해당되는 집단 함수가 없어도 다른 집단 함수를 조합하여 원하는 집단 함수를 얻을 수 있다. 예를 들어 AVG(SALARY)는 SUM(SALARY) / COUNT(SALARY)로 구할 수 있다.

다음은 집단 함수의 적합성을 조사한 표이다.

목표 집단 함수필요 집단 함수
AVG(expr)SUM(expr), COUNT(expr)
SUM(expr)AVG(expr), COUNT(expr)
STDDEV(expr)VARIANCE(expr)
(STDDEV_SAMP(expr), STDDEV_POP(expr), VAR_SAMP(expr), VAR_POP(expr)) 중 하나, COUNT(expr)
SUM(expr * expr), SUM(expr), COUNT(expr)
STDDEV_SAMP(expr)VAR_SAMP(expr)
(STDDEV(expr), STDDEV_POP(expr), VARIANCE(expr), VAR_POP(expr)) 중 하나, COUNT(expr)
SUM(expr * expr), SUM(expr), COUNT(expr)
STDDEV_POP(expr)VAR_POP(expr)
(STDDEV(expr), STDDEV_SAMP(expr), VARIANCE(expr), VAR_SAMP(expr)) 중 하나, COUNT(expr)
SUM(expr * expr), SUM(expr), COUNT(expr)
VARIANCE(expr)STDDEV(expr)
(STDDEV_SAMP(expr), STDDEV_POP(expr), VAR_SAMP(expr), VAR_POP(expr)) 중 하나, COUNT(expr)
SUM(expr * expr), SUM(expr), COUNT(expr)
VAR_SAMP(expr)STDDEV_SAMP(expr)
(STDDEV(expr), STDDEV_POP(expr), VARIANCE(expr), VAR_POP(expr)) 중 하나, COUNT(expr)
SUM(expr * expr), SUM(expr), COUNT(expr)
VAR_POP(expr)STDDEV_POP(expr)
(STDDEV(expr), STDDEV_SAMP(expr), VARIANCE(expr), VAR_SAMP(expr)) 중 하나, COUNT(expr)
SUM(expr * expr), SUM(expr), COUNT(expr)

이기종 데이터베이스에서 실체화 뷰를 이용하여 Tibero에 있는 베이스 테이블의 데이터를 동기화하고 싶을 때 사용하는 기능이다.

이기종 데이터베이스에서 Tibero에 있는 베이스 테이블를 조회하는 실체화 뷰를 생성해도 빠른 리프레시는 수행이 불가능하다. 따라서 이 기능을 통해 실체화 뷰 관리를 Tibero쪽 데이터베이스가 담당하게 하고, 실제 저장소는 이기종 데이터베이스에 위치하게 하여 조회가 가능하게 한다. 현재 이기종 데이터베이스는 Oracle만 지원한다.

아래 설명을 하기 전에 베이스 테이블이 위치한 데이터베이스를 A, 실체화 뷰 저장소 테이블이 위치할 오라클 서버를 B이라 가정한다.