쿼리가 느려요... 0 5 2,048

by 망뎅이 [2014.01.10 15:52:49]


select
  sum(decode(code2, '01', 3500, '02', 3500, '03', 3500, 0)) a,
  sum(decode(code2, '04', 6000, '05', 6000, '06', 6000, 0)) b
from ( 
 select
  (select code2 from table2 where code = t1.code1) code2
 from (
  select
   code1
  from table1
  where model = '1111'
   and type = '1'
 ) t1
);

어떠한 테이블의 데이터를 가지고 와 금액을 계산하는 쿼리를 위와 같이 짰습니다... 안쪽의 select 구문에서는 속도가 빨리 나오는데... sum(decode... 구문까지 함께 실행하면 쿼리의 속도가 엄청 느려지는 문제가 있습니다.
대략.... table1 테이블은 데이터가 250만건, table2는 그 4배 이상의 데이터가 있는 테이블입니다.

인덱스는 타고 있는데... 조회가 1분 30초 정도 걸립니다... 왜 이렇게 느린걸까요.. 고수님의 답변 기다리겠습니다~ ㅠ
by 용근님 [2014.01.10 15:59:05]
블럭 안에 있는 쿼리만 별도로 '전체'를 조회 한다면 데이터가 꽤될거 같습니다.

그리고 table2가 Code 성인가요? Code 성 테이블이 아니라면 Join으로 한번 풀어보세요



select
  sum(decode(code2, '01', 3500, '02', 3500, '03', 3500 )) a,
  sum(decode(code2, '04', 6000, '05', 6000, '06', 6000 )) b
  from ( 
          select code2
            from table1 a
               , table2 b
            where a.model = '1111'
              and a.type  = '1'
              and a.code  = b.code
)

by 망뎅이 [2014.01.10 16:01:58]
code성 테이블은 아니구요, 데이터가 많이 존재합니다... ㅠㅠ join이 더 느려서 쿼리를 위와 같이 작성했습니다 ㅠㅠ

by 마농 [2014.01.10 16:34:57]

스칼라서브쿼리가 에러 없이 동작했다는 것은
table1.code1 에 해당하는 table2.code 의 값이 중복없는 유일값이라는 거네요.
table2.code 에 인덱스는 있겠죠?

WHERE a.model = '1111' AND a.type  = '1' 를 만족하는 table1 의 수는 전체 몇건중 몇건인가요?
해당 조건으로 인덱스는 타나요?
table1.code1 의 데이터는 중복값이 존재하나요? 중복값이 존재한다면 code1 별 대략 몇건정도?

table2 는 전체 몇건?

위 질문들에 모두 답변 주세요.


by 마농 [2014.01.10 18:07:02]
-- 음... 질문에 답이 없으시네요? 바쁘신가? 일단 쿼리 올려봅니다.
-- 1. Group By 를 통해 중복을 제거하여 조인 부하 줄이기
-- 2. Group By code2 중간집합을 이용하여 Decode 사용 부하 줄이기
-- 3. 위 1,2 번을 수행하기 위해 Sum 방식을 Count 방식으로 변경
SELECT SUM(CASE WHEN code2 IN ('01','02','03') THEN cnt ELSE 0 END) * 3500 a
     , SUM(CASE WHEN code2 IN ('04','05','06') THEN cnt ELSE 0 END) * 6000 b
  FROM (SELECT b.code2
             , SUM(a.cnt) cnt
          FROM (SELECT code1
                     , COUNT(*) cnt
                  FROM table1
                 WHERE model = '1111'
                   AND type  = '1'
                 GROUP BY code1
                ) a
             , table2 b
         WHERE a.code1 = b.code
         GROUP BY b.code2
        )
;

by 꼬랑지 [2014.01.10 17:43:54]

DECODE 문은 데이터가 많을 수록 성능부하가 심한 걸로 아는데 CASE문으로 변경하면 어떨까요?
그리고 0 을 SUM 하는 것은 의미가 없으므로 해당 코드가 아닐 때 0을 반환하도록 하는 로직도 필요 없을 것 같은데요?
select
  sum(CASE WHEN code2 IN ( '01', '02', '03') THEN 3500 END) a,
  sum(CASE WHEN code2 IN ( '04', '05', '06') THEN 6000 END) b
from (
)
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입