database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
ㆍOracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
Oracle Q&A 40921 게시물 읽기
No. 40921
SQL 해석좀 해주세요.
작성자
이현정
작성일
2015-09-03 17:14
조회수
8,330

SELECT B.UOM

,B.QTY

,NVL(M.WGT_UOM, 'KG') AS WGT_UOM

 

FROM B_ORD B

,M_ORD M

WHERE B.NO = '108'

AND B.DRDR = ' '

AND B.KND IN ('EAC')

 

--요기요.

AND B.M_NO LIKE CASE WHEN M.MSCC = 'D' THEN '108A1%'

ELSE 'A1%'

END

--해석이 안되요.

 

AND B.M_NO = M.M_NO ;

 

위의 SQL이 있는데요.

 

플랜을 보면

B_ORD 테이블이 먼저 풀리고 M_ORD가 풀리는 형태입니다.

상식적으로 보면 M.MSCC가 있어서 먼저 풀려야 되질 않나 싶은데

옵티마이져는 B_ORD를 먼저 선택을 하네요.

 

위 내용의 구문을 어떻게 해석해야 하나요?

아무리 봐도 무슨 작업을 할려고 하는지 이해가 안가서요.?

 

다르게 고친다면 ? ^^;

 

이 글에 대한 댓글이 총 3건 있습니다.

SELECT b.uom
     , b.qty
     , NVL(m.wgt_uom, 'KG') AS wgt_uom
  FROM b_ord b
     , m_ord m
 WHERE b.no = '108'      -- ①
   AND b.drdr = ' '      -- ②
   AND b.knd IN ('EAC')  -- ③
   AND b.m_no LIKE CASE WHEN m.mscc = 'D' THEN '108A1%' ELSE 'A1%' END -- ④
   AND b.m_no = m.m_no   -- ⑤
;


5개의 조건이 있습니다.
이중 상수값과 비교하는 ①,②,③ 은 검색조건이구요.
테이블끼리 비교하는 ④,⑤ 는 조인조건입니다.
조인 조건만 보고 실행 방향을 예측할 수는 없습니다.
이해가 안간다고 한 ④번 조건은 b 와 m 의 조인조건 인데요.
m 을 가공했다고 b 를 나중에 읽어야 한다고 말할 수는 없습니다.


조인의 방향은 결과를 줄여주는 쪽을 먼저 드라이빙합니다.
많은 양을 조인한 뒤 걸러내는 것보다는
미리 걸러낸것만 조인하는게 유리합니다.
검색조건이 b 에만 걸려있네요.
당연히 b 를 먼저 드라이빙할 확률이 높아집니다.


④번 조건의 b.m_no 를 m.m_no 로 바꾸어도 결과는 동일합니다.
이렇게 바꾸면 ④번 조건은 조인조건이 아닌 검색조건이 될 수 있습니다.
이렇게 되면 m 을 드라이빙할 확률이 약간은 올라가겠지요.
그래도 b 를 먼저 읽을 확률이 더 높을 듯 하네요.

마농(manon94)님이 2015-09-03 18:51에 작성한 댓글입니다.
이 댓글은 2015-09-03 18:54에 마지막으로 수정되었습니다.

 SELECT

B.UOM
,B.QTY
,NVL(M.WGT_UOM, 'KG') AS WGT_UOM
FROM B_ORD B
,M_ORD M
WHERE B.NO = '108'
AND B.DRDR = ' '
AND B.KND IN ('EAC')
AND B.M_NO LIKE CASE WHEN M.MSCC = 'D' THEN '108A1%' ELSE 'A1%' END
AND B.M_NO = M.M_NO ;
 
각각의 테이블의 데이타양과 키 구조를 알려주시면 더 좋을 듯 합니다.
 
위의 sql은 다음의 sql과 등가입니다.
 
 
SELECT
B.UOM
,B.QTY
,NVL(M.WGT_UOM, 'KG') AS WGT_UOM
FROM B_ORD B
,M_ORD M
WHERE B.NO = '108'
AND B.DRDR = ' '
AND B.KND IN ('EAC')
and M.MSCC = 'D'
AND B.M_NO LIKE '108A1%'
AND B.M_NO = M.M_NO
union all
SELECT
B.UOM
,B.QTY
,NVL(M.WGT_UOM, 'KG') AS WGT_UOM
FROM B_ORD B
,M_ORD M
WHERE B.NO = '108'
AND B.DRDR = ' '
AND B.KND IN ('EAC')
and nvl(M.MSCC,'_$_') != 'D'
AND B.M_NO LIKE 'A1%'
AND B.M_NO = M.M_NO
 
위에서 님께서 왜 M_ORD가 먼저 타지 않는지 궁금하다고 하신 점으로 보아
M_ORD 테이블의 행의 수가 적으리라 보입니다.
그리고 그렇지 않다 하더라도  아마도 m_no 컬럼이 'A1%' 인 것과 '108A1%'인 것을 합쳐도 전체
B_ORD의 행의 갯수에 비하면 작은 행의 데이타만 해당 되겠죠?
 
그렇지 않다면 M_ORD를 먼저 타게 하려는 시도는 무의미합니다.
왜냐면 그런 경우 B_ORD 테이블의 no,drdr,knd에 걸려 있는 필터 조건이 유효하거나
해당 컬럼만으로 유효 인덱스 접근이 가능하거나 풀스캔이 유리한 경우이므로 M_ORD를 먼저 타게 하시려는 시도를 할 필요가 없죠?
 
제 생각에는 아마도 m_no가 인덱스의 선행 컬럼으로 설계되어 있으며 no,drdr,knd가 그 인덱스에 참여하고 있을 가능성이 있어 보입니다.
그런데 
AND B.M_NO LIKE CASE WHEN M.MSCC = 'D' THEN '108A1%' ELSE 'A1%' END
이 부분이 조건적인 조인이 되다보니 인덱스를 참조 못하는 것 같아서 질문을 올리시지 않았나 생각됩니다.
 
김흥수(protokhs)님이 2015-09-04 08:46에 작성한 댓글입니다.

정말 감사합니다. ~~~

 

재미있는 분야입니다. ^^

 

이현정님이 2015-09-04 09:04에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
40924optimzier_features_enable 파라메타 관련
우태열
2015-09-05
7801
40923동일 DB에 USER1 에서 USER2 를 DBLINK로 연결 [1]
반건마
2015-09-04
7904
40922오라클 설치에 관한 질문입니다. [1]
현동헌
2015-09-04
7884
40921SQL 해석좀 해주세요. [3]
이현정
2015-09-03
8330
40920디폴트 idle timeout 값 [4]
8925
2015-09-02
9393
40919테이블에 컬럼 생성일시와 누가 생성했는지 확인 가능하나요? [1]
정준민
2015-09-01
8096
40917오라클 클라이언트와 엔진의 차이? [2]
초보자
2015-09-01
8102
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.017초, 이곳 서비스는
	PostgreSQL v16.4로 자료를 관리합니다