.....
.....
FROM LTAK AS A JOIN LTAP AS B
ON B~LGNUM = A~LGNUM
AND B~TANUM = A~TANUM
LEFT JOIN MARA AS C
ON C~MATNR = B~MATNR
LEFT JOIN LAGP AS D
ON D~LGNUM = B~LGNUM
AND D~LGTYP = B~VLTYP
AND D~LGPLA = B~VLPLA
LEFT JOIN LAGP AS E
ON E~LGNUM = B~LGNUM
AND E~LGTYP = B~NLTYP
AND E~LGPLA = B~NLPLA
WHERE A~LGNUM = P_LGNUM
AND A~TRART IN GR_TRART
AND A~BDATU IN S_BDATU
AND A~BENUM IN S_BENUM
AND B~WERKS IN S_WERKS
AND B~LGORT IN S_LGORT
AND B~VLTYP IN S_VLTYP
AND B~TANUM IN S_TANUM
AND B~MATNR IN S_MATNR
AND B~QNAME IN S_QNAME
AND B~PQUIT IN GR_PQUIT.
위와 같은 SQL문이 있는데 속도가 나질 않아 INDEX를 생성하려 합니다.
INDEX를 어떤 테이블에 필드로 해야 속도가 날까요?
댓글 7
-
요요
2009.12.09 02:44
-
Risky
2009.12.09 18:34
질문에 질문 드려서 죄송한데요,
오라클에서는 left Outer Join 할 때,
where E.LGNUM = B.LGNUM(+) 할 경우하고,
where E.LGNUM(+) = B.LGNUM 한 경우하고 결과가 다른데요,
FROM LTAP AS B LEFT JOIN LAGP AS E
ON E~LGNUM = B~LGNUM 한 결과랑,
FROM LTAP AS B LEFT JOIN LAGP AS E
ON B~LGNUM = E~LGNUM 결과가 다르지 않나요??? -
Jon
2009.12.09 19:33
Risky 말씀하신거 리플달아봅니다.
1.
where E.LGNUM = B.LGNUM(+) 할 경우하고,
where E.LGNUM(+) = B.LGNUM 한 경우하고 결과가 다른데요,
==> Alials E 와 Alias B 테이블을 아웃터 조인 걸었을 경우, 기준이 되는 테이블이 다르니 당연히 결과값이 다를것으로 생각됨.
2. FROM LTAP AS B LEFT JOIN LAGP AS E
ON E~LGNUM = B~LGNUM 한 결과랑,
FROM LTAP AS B LEFT JOIN LAGP AS E
ON B~LGNUM = E~LGNUM 결과가 다르지 않나요???
==> 이부분은 조인 컬럼 순서만 바꼇기 때문에 결과값은 같을것으로 생각됩니다.
아웃터 조인될때, 기준이 되는 테이블은 이미 FROM 절에서 결정하셧기 때문에 ON(WHERE)절에서
조건 필드 순서는 무관할것같네요.
-
요요
2009.12.09 19:53
Jon 님이 설명 잘 해주셨네요. 결국 두 테이블 모두 조인되는 조건이 인덱스를
잘 타게 구현하시면 됩니다. 필요하시다면 만드셔야 하구요. SQL trace 걸어서
인덱스가 잘 타는지 어떻게 구성되었을 경우 인덱스의 효율성이 높은지 테스트 해보시는
습관을 가지시는 것도 좋을 것 같습니다. 필요하다면 인덱스를 만들어서 테스트
해보시고 가장 효율 높은 인덱스를 채택하시는 것도 방법일 수 있구요. ^^
좋은 결과 있으시길 바랍니다.
-
Jon
2009.12.09 19:59
아밥님 글에 리플달아봅니다.
FROM LTAK AS A JOIN LTAP AS B
ON B~LGNUM = A~LGNUM
AND B~TANUM = A~TANUM
LEFT JOIN MARA AS C
ON C~MATNR = B~MATNR
LEFT JOIN LAGP AS D
ON D~LGNUM = B~LGNUM
AND D~LGTYP = B~VLTYP
AND D~LGPLA = B~VLPLA
LEFT JOIN LAGP AS E
ON E~LGNUM = B~LGNUM
AND E~LGTYP = B~NLTYP
AND E~LGPLA = B~NLPLA
WHERE A~LGNUM = P_LGNUM
AND A~TRART IN GR_TRART
AND A~BDATU IN S_BDATU
AND A~BENUM IN S_BENUM
AND B~WERKS IN S_WERKS
AND B~LGORT IN S_LGORT
AND B~VLTYP IN S_VLTYP
AND B~TANUM IN S_TANUM
AND B~MATNR IN S_MATNR
AND B~QNAME IN S_QNAME
AND B~PQUIT IN GR_PQUIT.
==> 우선 제가 지금 있는곳에닌 해당 테이블들을 사용하지 않아 틀린 답변이 될수도 있을음 말씀드립니다.
위 해당 쿼리를 봤을 경우.
LTAK JOIN LTAP 는 PRIMARY INDEX 로 JOIN(LTAP는 TAPOS 제외한)을 타게 됩니다.
또한 MARA 테이블 또는 마찬가지입니다.
INNER JOIN 보다 OUTER JOIN이 당연히 많은 DATA 를 SCAN해야 하므로, 성능이 더 떨어지게 됩니다.
위 쿼리에서도 눈으로 봤을때는 , LEFT OUTER JOIN LAGP 2번 하는 부분에서 많은 시간이 걸릴것으로 보입니다.
구구절절 설명은 여기까지만 하고 문제점으로 보이는 곳을 찍어보겠습니다.
1. LTAK 테이블의 인덱스 활용.
- LGUNM , TANUM이 PROMARY KEY 이므로 , TANUM이 검색조건으로 들어오게한다.(최상의 조건)
- DB05 T-CODE에서 확인하여, 조건으로 들어오는 DISTINCT VALUE 값이 큰 순서로 인덱스 생성
(예 - MANDT + LGNUM + DISTINCT VALUE 값이 크고 필수 조건으로 들어오는 필드 순서로 생성)
2. LAGP 테이블의 OUTER JOIN 2번 하는 부분.
- LAGP 테이블을 2번 SCAN 하므로. 1회로 줄이는 방법을 고려.
(해당 쿼리에서 LAGP 부분만 빼서 다른 방법으로 구현/ 상황에 따라 다르므로 생략함)
-
Risky
2009.12.09 20:30
Jon 답변 감사드립니다. ^^;;; -
아밥
2009.12.10 22:50
리플 감사드립니다.
많은 도움 됐습니다.
글쎄요. 좀 복잡하긴 하네요.
일단은 join 으로 연결된 필드에 대하여 각 테이블에
해당 조인조건이 index 적용이 되는지 봐야 할 것 같구요.
where 조건으로 들어오는 조건중에 필수로 들어오는 값을 먼저 지정하시구요.
해당 테이블 필드 조건에 대하여 경우의 수별로 데이터의 분포가 어떻게 되어 있나
확인하신후에 가장 고르게 분포되어 있는 데이터조합을 기준으로
index 를 생성하시면 될 것 같습니다.
꼭 조건에 대한 필드만 보시지 마시고 필요하다면 한두개 정도
상수조건으로 주실수있는 필드나 회사코드, 플랜트 같은 조건값이 얼마 안되는 것도
기준을 잡고 보시면 될 겁니다.
데이터가 아주많이 몰려 있는 경우에 조건이 주어진다면 검색범위가 넓어지기 때문에
인덱스로서 의미가 별로 없을 지도 모르기 때문입니다. 좋은 결과 있으시길...