case null check 성능개선 방법이 뭐가 있을까요? 0 8 1,626

by 파워간 [SQL Query] [2018.07.18 10:47:05]


안녕하세요

a라는 테이블과 c라는 테이블을 조인을 걸어 데이터를 가져오는 관계입니다.

a.acol 컬럼과 c.acol컬럼이 두개다 인덱스가 걸려있어 오래걸리지 않을것으로 예상했는데

생각보다 느려서 확인했더니

case 문을 이용해서 acol이 null일경우 데이터 전체 리스트를 가져오고 not null 일 경우 해당 리스트를 가져올걸 예상했는데

데이터가 null 이 아닌 경우도 엄청 느리더라고요

튜닝 가이드 부탁드립니다 ㅜㅜ

 

null인경우에는 느린게 이해가 되는데 not null 인경우에도 느려서 문의드려요.

혹시 좋은 방법 아시는분 공유 부탁드리요.

 

<기존쿼리>

select a.acol, a.bcol, c.ccol

from a_table a, c_table c

where 1=1

and a.acol = c.acol

and a.acol = case

                      when :b0 is not null then :b0

                      else a.acol

                    end;

-> tableacess a테이블

-->nested loop

--->c테이블 fast fullscan

--->a 테이블 Index uniquscan

 

< null 이 아닌경우 >

null 이 아닌경우 아랫 쿼리같이 풀려 빠를것으로 예상하였지만 느리더라요

select a.acol, a.bcol, c.ccol

from a_table a, c_table c

where 1=1

and a.acol = c.acol

and a.acol = :b0

-> a.acol unique scan으로 빨리 풀림

by 우리집아찌 [2018.07.18 11:00:22]

a_table 의 COL 컬럼에는 index가 잡혀있나요?

 


by 파워간 [2018.07.18 11:17:46]

쿼리 수정했습니다.

a_table, b_table

두개다 acol 이 unique 인덱스로 설정되어 있습니다.


by 우리집아찌 [2018.07.18 11:23:15]
-- 이렇게 해보세요.,
--null 이 아닌경우
select a.acol, a.bcol, c.ccol
  from (select rowunm rn , aa.* from a_table aa where aa.acol = :b0 )   a
     , c_table c
 where 1=1
   and a.acol = c.acol

 


by 파워간 [2018.07.18 12:27:23]

위 case문 쿼리가 null 아닌경우 아래처럼 unique 스켄으로 풀렸으면 좋겠는데 안풀려서요 ㅜㅜ

실제로는

-> tableacess a테이블

-->nested loop

--->c테이블 fast fullscan

--->a 테이블 Index uniquscan

 

이렇게 풀리고 있어서요

 

< null 이 아닌경우 >

select a.acol, a.bcol, c.ccol

from a_table a, c_table c

where 1=1

and a.acol = c.acol

and a.acol = :b0


by jkson [2018.07.18 12:12:41]
select a.acol, a.bcol, c.ccol
from a_table a, c_table c
where 1=1
and a.acol = c.acol
and a.acol = nvl(:b0,a.acol);

by 파워간 [2018.07.18 13:36:26]

감사합니다 nvl로 해결되었습니다 ^^


by 마농 [2018.07.18 12:52:23]
-- 조건값이 들어오는지? 안들어오는지에 따라 실행계획이 분리되어야 합니다.
-- 실행계획에 Conacatenation 이 등장하는지 확인하세요.
-- Case 문 대신 Decode 나 NVL 로 바꿔보세요.
SELECT a.acol
     , a.bcol
     , c.ccol
  FROM a_table a
     , c_table c
 WHERE 1=1
   AND a.acol = c.acol
   AND a.acol = NVL(:b0, a.acol)
--   AND a.acol = DECODE(:b0, null, a.acol, :b0)
--   AND a.acol = CASE WHEN :b0 IS NOT NULL THEN :b0 ELSE a.acol END
;

 


by 파워간 [2018.07.18 13:36:20]

감사합니다 nvl로 해결되었습니다 ^^

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