각 지점별로 제품들에 관한 특정 기간별 누적 매출을 조회하는 리포트 프로그램의 일부입니다.
일단 특정 기간을 한달 정도로 정하고 조회하면 데이터가 보통 200만건 정도 됩니다.
각 제품별로 정해진 매출 정가가 있으며
각 지점과 자재번호 별로 이 매출 정가들을 sum 하면
각지점별 해당 제품들에 대한 매출이 됩니다.
* 누적
SELECT 자재번호 지점코드 SUM( 매출정가 )
INTO TABLE ITAB1
FROM 매출정보
WHERE 보급년월 IN V_MONTH AND "V_MONTH는 parameters입니다.
지점코드 IN V_PRCTR AND "V_PRCTR는 parameters입니다.
자재번호 IN MATNRS AND "MATNRS는 가상테이블입니다.
매출정가 <> '0'
GROUP BY 자재번호 지점코드
%_HINTS ORACLE 'INDEX(매출정보, "매출정보~Z01")'.
SORT ITAB1 BY 지점코드.
위와같은 select문을 사용해서 정보를 가져오는데 이 select문만 2분 걸립니다.
200만건이 양이 좀 된다고 해도 너무 느린것이지요.
위의 select문을 더 빠르게 고쳐서 1분정도에 결과가 나오게 할 방법이 없을까요?
1분만에 결과를 나오게 하라고 요청받았습니다.
프로그램 성격상 보급년월, 자재번호, 지점코드 이런것 이외에 검색조건으로 줄 수 있는 항목이 없더군요.....
도움의 손길을 기다립니다!!!!! |ㅠㅠ/
P.S) select문에서 sum을 안쓰고 가상테이블에 into 시켜도 2분이상 걸립니다.
P.S2) INDEX 생성은 제 마음대로 할수가 없더군요. 권한이 없습니다.
P.S3) INDEX Z01은 MANDT, 보급년월, 지점코드, 계정그룹 으로 구성되어 있습니다. Z01 INDEX가 제가 원하는 항목이랑 완전하게 일치하진 않지만 그나마 가장 근접한것이라 사용하였고, INDEX는 제 마음대로 건드릴수가 없습니다.
댓글 9
-
activeman
2008.04.03 19:02
-
onefineday
2008.04.03 19:06
현재 구문에서는 힌트 문장으로 강제적으로 인덱스 매출정보~Z01을 타도록 구성이 되었는데,
인덱스 매출정보~Z01의 구성이 어떻게 되어 있는지요?
실제 쿼리의 V_MONTH , V_PRCTR의 값이 파라미터로 되어있다면 EQ조건으로 전환이 될테고
혹 MATNRS에 값을은 어떻게 담기는 지여? 가상테이블이란 말이 RANGE 나 SELECT-OPTION을 말씀하시는것 같은데
만약 그렇다면 RANGE 값이 어떻게 담기는 지에 따라 Native SQL 전환이 다양하게 되기 때문에 ... 좀 까다로울거 같네요.
그리고 쿼리문장의 매출정가 <> '0'는 필요없는 구문 같구요, <>조건은 인덱스를 타지도 않을뿐더러 어차피 금액 SUM 값을 구하는 거니깐요.
일단 위의 쿼리만으로 봐서는 심플하게...보급년월,지점코드,자재번호,매출정가로 인덱스를 하나 생성해보셔도 될듯합니다.
(물론 기존 테이블의 인덱스가 어떻게 되어 있는지를 먼저 고려해야 겠지요...)
-
NT
2008.04.03 19:22
제 위치가 테이블이나 인덱스를 마음대로 생성할 수 없고 주어진것만 사용해야 합니다.
그리고 MATNRS의 경우 프로그램 실행시 특정 제품을 검색조건에 추가할때만 값이 들어갑니다.
검색 조건에 제품코드를 넣지 않으면 비어 있지요.
프로그램 실행시 검색 조건으로 줄 수 있는건 손익센터 그룹, 지점코드, 기간, 제품정보 등입니다.
손익센터 그룹은 그냥 지점 명 같은거만 가져오고 처리도 빠릅니다.
마지막으로 매출정가 <> '0'의 경우는 나중에 화면에 출력할때 값이 0인 매출 정보가 나오지 않게 하기 위해서 사용합니다.
-
가오만땅
2008.04.03 19:38
st05 에서 쿼리 트레이싱 해보시고..(콩글리쉬 작렬.. ㅎㅎ) full table scan 이 어디에서 일어나는지 확인해 보셔야겠어요.
onefineday 님이 말씀하셨듯이.. <> 는 삭제 하시고 internal table 단에서 처리하시면 어떨까요?
인덱스를 생성할수 있다면.. 기존 인덱스에 잡혀있는 값은 모두 where 절에 포함시키는 것도 퍼포먼스 향상에 도움이 된다고 합니다.
all 조건일지라도 range 잡아서 태워보시는것도 의미가 있을것 같네요..
일할수 있는 조건이 너무 제약적이네요;;
-
SAP폐인
2008.04.03 19:40
200만건을 ;; 차라리 Work Process가 허용한다면 병렬처리로 돌려서.. 40*5개로 나눠서 처리하심이 어떠실지요.. 100만건 넘어가면 일단 속도때문에.. 병렬로 나눠서 처리해주는게 ... 빨리빨리에 적응하는 방법이라고 생각됩니다만.. -
초보아밥퍼
2008.04.03 19:46
흠 전쟁터에 총도 안주고 칼가지고 싸우라고 하다니 나빠요 ㅋ...
인덱스 생성 원츄~~ 권한도 안주면서 2분을 -> 1분으로 하라는건 억지죠...
역시나 <> 구절은 퍼퍼먼스 떨어지니 가오만땅님 말처럼 0인걸 안보이시려면
셀렉트 문에선 제거 하시고 인터널 테이블 선에서 처리하시는게 좋을듯 하네요.
역시 셀렉트 퍼퍼먼스 쪽이라 답글들 금방 다셨네 ^^
-
onefineday
2008.04.03 21:40
인덱스 매출구조~Z01의 구성이 MANDT, 보급년월, 지점코드, 계정그룹 이라면, 위의 쿼리로는 Index range scan 후 다시 table access가
발생될것입니다. 그리고 강제로 힌트구문 주지 않아도 Optimizer에서 where절의 조건에 맞게 인덱스 매출구조~Z01을 선택할것 같구요.
지금 2분 걸리는 상황에서 1분으로 단축하라면서 인덱스 생성도 금지한다면...^^ 좀 무리인것 같네요.
현재 문장을 가지고 ABAP 튜닝을 통해서는 개선될 부분은 없는것 같구요.
현재 테이블에 인덱스가 몇개가 생성되어있는지는 모르겠지만, 말씀드린대로 한개더 생성 요청 해보세요...
한달치 200만건이라 전체 테이블의 크기가 커서 BC쪽에서 부담스러워할수도 있겠지만, 인덱스 추가해보고 별로이다 싶으면^^ 지워도
무방하니깐요.
아. 그리고 매출정가가 0이 아닌 부분을 출력안하게 하기 위한 것이면, 가오만땅님 말씀대로 인터널테이블 단에서 삭제하시는게 나을거 같구요, 만약에 인덱스를 생성하신다면, 추가 인덱스에 매출정가가 포함되어 있으니, 쿼리문장에서 삭제할 필요는 없을것 같습니다.
인덱스 생성해달라고 해보시구... 안된다고 하면^^ 튜닝업체 부르라고 하세요...^^ 각기 역할이 있는 거니깐 ABAPer한테 튜닝까지 해달라고 하면 안되죠^^ (튜닝업체 부르겠다면 좋은 업체 소개시켜드릴께여 ㅋㅋㅋ)
수고하시공... 도움이 되면 좋겠네요...
-
SD2
2008.04.04 02:39
CO쪽인가바여?
-
NT
2008.04.04 02:44
도움주신 분들 감사합니다.
일단 주어진 상황에선 2분의 벽을 깨기가 힘들지만 서버 상황이 좋으면 35초만에도 나옵니다.
느리면 5분이구요.
많은 도움이 되었습니다.
헉..200만건을 한번에 불러 오시겠다니 대단하십니다...
데이터 양이 너무 많은 것은 아닐까요..
매출정가 <> '0' 항목을 삭제해 보시죠.. 이항목이 있으면 full table scan 이 일어나서 인덱스가 안 먹힙니다.
그리고 인덱스가 뭘로 구성되어 있는지 궁금합니다..
인덱스가 3~4개 이하이고 자재번호 지점코드에 대한 인덱스가 없다면
자재번호, 지점코드에 대한 인덱스를 생성하는게 어떨까요..
사용하는 프로그램의 빈도가 높다면 집계테이블을 하나 만드는것도 좋은 방법일텐데요.
즐밥하세요..