Union all 부분범위처리 문제 1 4 3,350

by 조민수 union all [2009.06.30 15:30:01]


^^ 고수님들의 조언을 구합니다.

다름 아니라 저희시스템에 뷰가 하나 있는데요

 T_VIEW(가칭)라는 무지막지하게 느린넘이 하나 있습니다.

이뷰의 구조를 보면 9개의 쿼리가 union all로 더해져 있습니다.

9개의 쿼리결과를 한번에 볼때도 있을수도 있지만,

일반적으로 저 뷰를 조회할때는  flag라는것을 주고

저flag가 뭐냐에 따라서 T_VIEW뷰 안의 union all중 하나의 쿼리만 조회합니다.

그런데~~~!! 실제 돌려보니 9개의 모든 쿼리를 다 찔러 본다는 겁니다.

우선 샘플을 보여드리겠습니다.

================================================================

-- 요런식으로 씁니다.

select *
  from T_VIEW
 where Flag = ’1’

혹은

select *
  from T_VIEW
 where Flag = ’3’
...

 

 뷰 구조는 아래와 같습니다.

CREATE OR REPLACE VIEW T_VIEW
(   Flag,
    a,
    b
)
AS
select ’1’ Flag, a_view.a a, a_view.b b from a_view -- 50만건 들어있는 뷰
union all
select ’2’ Flag, b_view.a a, b_view.b b from b_view -- 60만건 들어있는 뷰
union all
select ’3’ Flag, c_view.a a, c_view.b b from c_view -- 70만건 들어있는 뷰
union all
select ’4’ Flag, d_view.a a, d_view.b b from d_view -- 80만건 들어있는 뷰

union all
...

이런 select 절이 9개

;

 ========================================================

질문 드립니다. 저 뷰를 조회할때 Flag를 3으로 주면

DB가 3번 쿼리만 엑세스하게 할수 없을까요?

현재 3으로 주면 1~9까지 다 엑세스해서 너무나 느립니다 ㅠㅠ

작은 조언이라도 해주시면 정말 감사하겠습니다.
;

by 웅 [2009.06.30 17:03:44]
음.. 위의 케이스는 제가 알기로 님께서 기대하는데로 되야 하는걸로 알고 있어서 간단히 테스트해보니 해당 집합만 읽어오는 것을 확인했습니다.
혹시 실행계획으로 확인하신듯??..트레이스라든지 dbms_xplan.display_cursor 로 확인해보시고 실제 절대일량자체가 많아서 늦는지 확인해보시는게 우선일듯 합니다.

-------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------------------------------------------
| 1 | VIEW | | 1 | 99967 | 4100K| 49 (7)| 00:00:01 | 100K|00:01:16.55 | 6853 |
| 2 | UNION-ALL | | 1 | | | | | 100K|00:00:53.94 | 6853 |
|* 3 | FILTER | | 1 | | | | | 0 |00:00:00.01 | 0 |
| 4 | TABLE ACCESS FULL| TESTT | 0 | 98400 | 768K| 49 (7)| 00:00:01 | 0 |00:00:00.01 | 0 |
|* 5 | FILTER | | 1 | | | | | 0 |00:00:00.01 | 0 |
| 6 | TABLE ACCESS FULL| TESTT2 | 0 | 99782 | 779K| 49 (7)| 00:00:01 | 0 |00:00:00.01 | 0 |
| 7 | TABLE ACCESS FULL | TESTT3 | 1 | 99964 | 780K| 49 (7)| 00:00:01 | 100K|00:00:12.42 | 6853 |
|* 8 | FILTER | | 1 | | | | | 0 |00:00:00.01 | 0 |
| 9 | TABLE ACCESS FULL| TESTT4 | 0 | 99727 | 779K| 49 (7)| 00:00:01 | 0 |00:00:00.01 | 0 |

by flyhun [2009.07.01 16:23:47]
엥? 뭔가가 이상한데요? filter 이거는 테이블을 읽으면서 그 값이 있을때 바로 빠져나오는 것인데요.. 실행계획을 보시면 full 로 읽고 filter 로 걸르는데요..
만약 1, 2, 4 의 테이블 처리하는 것이 0 row 라면 실행계획에서 test3 인 것만 full로 읽겠죠..
뭔가 좀 이상한듯.. 실제 처리 row 와 실제 처리 시간,, 한 번 테스트 해봐야 겠습니다..

by flyhun [2009.07.01 16:37:42]
오오.. filter(NULL IS NOT NULL) !! 안읽는군요!!

by 웅 [2009.07.01 17:04:27]
predicate를 확인해보셨군요. ^^
buffers를 보시면 실제 블럭을 읽어와 필터링을 한 후 버린것인지 판단할 수 있습니다.
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입