Mview 및 Mview VIEW LOG 생성후 의문점 1 12 10,125

by 채용근 [2013.03.13 10:11:33]



안녕하세요~

Mview 집계시 의문이 있어서 자문을 구합니다.

Mview 생성구문은

CREATE MATERIALIZED MV명
BUILD IMMEDIATE
REFRESH FAST
START WITH sysdate
NEXT trunc( sysdate ) + 1 + 1/24
ON DEMAND
ENABLE QUERY REWRITE
AS


Mview log 테이블 생성구문

create MATERIALIZED VIEW log on 테이블명 ;

이렇게 생성했을시.

소스테이블에 데이터가 입력이 되면 입력된 값에 대해 빠른 집계를 제공합니다.

하지만 UPDATE나 DELETE 가 소스테이블에서 일어난다음 아래구문을 실행하면

BEGIN
  DBMS_MVIEW.REFRESH('MVEW명', 'F');   
END;

ORA-32314: "MYSHOP"."TEST"의 REFRESH FAST는 삭제/갱신 후에 지원되지 않음
ORA-06512: "SYS.DBMS_SNAPSHOT",  2563행
ORA-06512: "SYS.DBMS_SNAPSHOT",  2776행
ORA-06512: "SYS.DBMS_SNAPSHOT",  2745행
ORA-06512:  2행
32314. 00000 -  "REFRESH FAST of \"%s\".\"%s\" unsupported after deletes/updates"
*Cause:    One or more deletes or updates has been performed on one or more
   of the detail tables referenced by the specified materialized
   view.  This materialized view does not support fast refresh after
   deletes or updates.
*Action:   Use REFRESH COMPLETE.  Note
   materialized view does not support fast refresh after deletes or
   updates using the DBMS_MVIEW.EXPLAIN_MVIEW() API.

이런 오류가 납니다. COMPLETE로 하게 된다면 오류는 안나지만 집계시에 로딩이 오래 걸릴꺼 같아

다른 방법이 없는지 아니면 FAST 말고 COMPLETE 자체도 느리진 않은건지 궁금합니다.
by 부쉬맨 [2013.03.13 10:49:51]
제가 기억하기론 fast 옵션을 주고 만든거에대해서는
수동으로 돌리지못하는걸로알고있슴
http://www.gurubee.net/lecture/1859
http://www.gurubee.net/lecture/1858

속도로인한 차이는 없어보임
언제 돌릴꺼냐 스캐줄러로 저녁시간때 DB가놀때 돌게 해주면될꺼같은데요
complte 옵션으로?


by 채용근 [2013.03.13 10:52:25]

COMPLETE 옵션 자체가 LOG에 있는 데이터로 추출하는게 아니라서

SELECT 테이블 전체로 재집계를 한다면 오래 걸릴꺼 같은데요


by 부쉬맨 [2013.03.13 11:13:12]
어떠한 작업을 하시는지를 모르기에
이걸보시면 이해하실꺼같네요.
옵션을 찾아서 사용하시면될꺼같아요.

REFRESH 절은 오라클이 MView의 데이터를 언제, 어떻게 Refresh 하는지를 결정 하는 방법입니다. Refresh 방법에는 ON COMMIT 방법과, ON DEMAND 방법 2 가지가 있습니다.

      ON COMMIT 은 기초 테이블에 Commit 이 일어날 때 Refresh 가 일어나는 방안이며, 이는 1 개의 테이블에 COUNT(*), SUM(*)과 같은 집합 함수를 사용하거나, MView에 조인만이 있는 경우, Group By 절에 사용된 컬럼에 대해 COUNT(col) 함수가 기술된 경우만 사용이 가능 합니다.

      ON DEMAND는 사용자가 DBMS_MVIEW 패키지 (REFRESH, REFRESH_ALL_MVIEWS, REFRESH_DEPENDENT) 를 실행 한 경우 Refresh 되는 경우 입니다.

  - Refresh를 하는 방법에는 FORCE, COMPLETE, FAST, NEVER의 4가지가 존재 합니다.

      COMPLETE : MView의 정의에 따라 MView의 데이터 전체가 Refresh 되는 것으로 ATOMIC_REFRESH=TRUE와 COMPLETE으로 설정한 경우 입니다.

      FAST : 새로운 데이터가 삽입될 때마다 점진적으로 Refresh 되는 방안으로 Direct Path나 Mview log를 이용 합니다.

      FORCE : 이 경우 먼저 Fast Refresh가 가능한지 점검 후 가능하면 이를 적용하고, 아니면 Complete Refresh를 적용 합니다.(디폴트)

      NEVER : MView의 Refresh를 발생시키지 않습니다


by 채용근 [2013.03.13 11:15:20]

정확한 질문은

COMPLETE (3년치 데이터) 자체의 속도가 느리지 않느냐?

그래서 생각한 방법은 FAST 인데 UPDATE와 DELETE시에는 오류가 나는데 다른 방안은 없느냐?

이점입니다.

by 부쉬맨 [2013.03.13 13:06:20]
FAST : 새로운 데이터가 삽입될 때마다 점진적으로 Refresh 되는 방안으로 Direct Path나 Mview log를 이용 합니다.

혹시 그냥 dml을 해도 에러가나나요?
저위테스트로보았을때 dbms로 강제로 MVIEW를 실행시키신거같은데..


by 마농 [2013.03.13 13:20:25]

Materialized View Log 생성할때
WITH Sequence 옵션을 주고 생성해야 할듯.


by 채용근 [2013.03.13 13:23:01]
부쉬맨 //
BEGIN
  DBMS_MVIEW.REFRESH('TEST', 'F');    <== Fast 실행 ( update Row Insert Row가 있다면 에러가 납니다. )
END;

마농 //
형님 그거 주고 했는데두 안돼요 ㅠㅠ 방안이 없을까요

by 부쉬맨 [2013.03.13 13:31:59]
DML작업이 없는 정상적으로 commit(트랜잭션) 이 다끝나고 
돌리시면 에러가안날꺼같은데요?


http://kosate.tistory.com/107


by 마농 [2013.03.13 13:32:45]
Sequence 와 Rowid 를 함께 줘봐~
네이년 검색해서 들어가면 보이는데 Url 치고 들어가면 못들어가네...
"Materialized View Log Sequence" 로 네이년에게 물어보면 까페 쪽에 검색내역 클릭해봤음.

by 채용근 [2013.03.13 14:30:56]

일단 두분의 말씀대로 카페나 구글에서 나오는 거의 모든 종류에 행위를 해본결과

FAST 옵션은 DELETE나 UPDATE가 이뤄졌을땐 어쩔수 없이 COMPLETE로 한번 돌려야 한다는 결과가 ...

일단 더 찾아보겠지만 신경써주신 두분께 무한 감사를 ^_^

by 채용근 [2013.03.13 14:37:01]

엇 방금 찾았네요... 겨우 찾았네 3일 검색 결과 ㅎㅎ

DELETE/UPDATE 까지 FAST로 반영하기 위해선 COUNT(*) 라는 항목이 무조건 들어가줘야되네요..

혹시나 나중을 위해 히스토리를 냄깁니다.


CREATE MATERIALIZED VIEW LOG ON SALE  WITH ROWID, SEQUENCE(SALE_AMT) INCLUDING NEW VALUES ;


CREATE MATERIALIZED VIEW TEST
BUILD IMMEDIATE
REFRESH FAST
START WITH sysdate
NEXT sysdate + 1/24
ON DEMAND
WITH ROWID
ENABLE QUERY REWRITE
AS
SELECT SUM(SALE_AMT), count(*) FROM SALE


- 인설트 후
INSERT INTO SALE VALUES ( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ) ;

COMMIT;


-- 정상수행
BEGIN
  DBMS_MVIEW.REFRESH('TEST', 'F');   
END;


-- 삭제 후
DELETE FROM SALE WHERE 컬럼 = '1';


COMMIT;


-- 정상수행
BEGIN
DBMS_MVIEW.REFRESH('TEST', 'F');
END;

감사합니다.!!! ^^

by 마농 [2013.03.13 14:51:58]

음... 스터디 할때 분명 했던 부분인것 같은데...
기억이 전혀 나질 안다가 들으니까 떠오르는구만...쩝...
Good Job.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입