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 40902 게시물 읽기
No. 40902
Plan결과 고수님 의견을 듣고 싶습니다.
작성자
궁금이.
작성일
2015-08-21 16:02
조회수
7,860

안녕하세요..오늘도 개발에 여념이 없는 개발자님들 화이팅입니다.

 

다름이 아니라 쿼리 실행결과 PLAN 결과가 두 종류가 있는데 어떤것이 좋은 방법인지 몰라서 고수님들께 의견을 듣고 싶습니다.

 

1번 쿼리

Execution Plan

--------------------------------------------------------------------------------

0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1 Bytes=60)

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'A TABLE'(TABLE) (Cost=2 Card=1 Bytes=47)

2 1 INDEX (RANGE SCAN) OF 'B INDEX' (INDEX (UNIQUE)) (Cost=1 Card=1)

3 0 TABLE ACCESS (BY INDEX ROWID) OF 'B TABLE' (TABLE) (Cost=2 Card=1 Bytes=60)

4 3 INDEX (RANGE SCAN) OF 'B INDEX' (INDEX (UNIQUE)) (Cost=1 Card=1)

5 0 TABLE ACCESS (BY INDEX ROWID) OF 'B TABLE' (TABLE) (Cost=2 Card=1 Bytes=49)

6 5 INDEX (RANGE SCAN) OF 'B INDEX' (INDEX (UNIQUE)) (Cost=1 Card=1)

7 0 TABLE ACCESS (BY INDEX ROWID) OF 'B TABLE' (TABLE) (Cost=2 Card=1 Bytes=70)

8 7 INDEX (RANGE SCAN) OF 'B INDEX' (INDEX (UNIQUE)) (Cost=1 Card=1)

9 0 TABLE ACCESS (BY INDEX ROWID) OF 'A TABLE' (TABLE) (Cost=2 Card=1 Bytes=60)

10 9 INDEX (RANGE SCAN) OF 'A INDEX' (INDEX (UNIQUE)) (Cost=1 Card=1)

 

2번 쿼리

Execution Plan

--------------------------------------------------------------------------------

0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=4 Card=1 Bytes=194)

1 0 MERGE JOIN (CARTESIAN) (Cost=4 Card=1 Bytes=194)

2 1 TABLE ACCESS (BY INDEX ROWID) OF 'A TABLE' (TABLE) (Cost=2 Card=1 Bytes=60)

3 2 INDEX (RANGE SCAN) OF 'A INDEX' (INDEX (UNIQUE)) (Cost=1 Card=1)

4 1 BUFFER (SORT) (Cost=2 Card=2 Bytes=268)

5 4 TABLE ACCESS (BY INDEX ROWID) OF 'B TABLE' (TABLE) (Cost=2 Card=2 Bytes=268)

6 5 INDEX (RANGE SCAN) OF 'B INDEX' (INDEX (UNIQUE)) (Cost=1 Card=2)

 

 

고수님들께서는 위 PLAN 만 알 수 있겠지만

1번 쿼리는

SELECT A.AAA

,(SELECT BBB FORM B

WHERE INDEX = A.INDEX) AS BBB

,(SELECT BBC FORM B

WHERE INDEX = A.INDEX) AS BBC

FORM A

 

이런 식이고 2번 쿼리는

SELECT A.AAA

,B.BBB

,B.BBC

FORM A, B

WHERE A.INDEX = B.INDEX(+)

 

제 생각은 1번 쿼리는 유니크 인덱스를 타기 때문에 1번이 좋은거 같기도 하다가 SELECT 절이 너무 많기 때문에

오히려 2번이 좋은가 하는 생각이 들어서요.. 아시겠지만 B TABLE에는 데이터가 없을 수 있습니다.

 

고수님들 의견을 듣고 싶습니다.

감사합니다.

 

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

 설계가 제대로 되어 있다면 두 쿼리가 성능이 거의 차이 없습니다.

 

그런데 좀 이상한 것은

1번 쿼리에서 테이블 b를 스칼라 서브쿼리로 접근할 때 유니크 인덱스에 대하여

범위 스캔을 하고 있다는 점입니다.

그 말은 잘 못하면 설계에 따라 to_many_rows 오류가 날 가능성이 있다는 말이므로

1번 쿼리는 아예 잘못된 쿼리일 수도 있습니다.

 

그리고 2번 쿼리에 머지 조인이 나오는 것으로 보아 설계에 문제가 있을 수 있어보입니다.

가능하면 설계 내용도 올려주시기 바랍니다

김흥수(protokhs)님이 2015-08-21 17:53에 작성한 댓글입니다.
이 댓글은 2015-08-21 17:54에 마지막으로 수정되었습니다.

댓글 감사합니다. 제가 조건절을 다 적지 않아서 약간 오해가 있으신 듯 합니다.

제대로 질문 안한 점 죄송합니다.

 

SELECT A.AAA

,(SELECT BBB FORM B

WHERE UNIQ_INDEX1= A.UNIQ_INDEX1

AND UNIQ_INDEX2 = A.UNIQ_INDEX3) AS BBB

FORM A

WHERE A.UNIQ_INDEX1 = ?

AND A.UNIQ_INDEX2 LIKE ? || %

 

A,B TABEL PK

UNIQ_INDEX1, UNIQ_INDEX2,UNIQ_INDEX3 항목이 PK이며 A, B TABLE 연관관계는 없습니다. (B TABLE이 공통테이블입니다.)

 

A.UNIQ_INDEX1 데이터를 B.UNIQ_INDEX1 항목에 삽입하며

A.UNIQ_INDEX3 데이터를 B.UNIQ_INDEX2 항목에 삽입합니다.

 

B.UNIQ_INDEX3 데이터는 자동생성이며 SEQ라해도 무방합니다.

A.UNIQ_INDEX2 LIKE 를 한 이유는 조건데이터와 UNIQ_INDEX2 일정 길이까지는 동일하나 UNIQ_INDEX2 길이가 조건 데이터보다 길이보다 더 크기 때문입니다.

 

감사합니다.

 

궁금이.님이 2015-08-24 12:29에 작성한 댓글입니다. Edit

 일단 스칼라 서브쿼리를 쓰시고 있는 이상

B 테이블이 UNIQ_INDEX1, UNIQ_INDEX2 만으로 유일성이 보장되겠죠?
그런데 그럼에도 불구하고 UNIQ_INDEX1, UNIQ_INDEX2,UNIQ_INDEX3 까지 PK라서
"INDEX (RANGE SCAN) OF 'B INDEX' (INDEX (UNIQUE)) (Cost=1 Card=1)" 이 나왔다는 말씀이신 것 같습니다.
(만약 UNIQ_INDEX1, UNIQ_INDEX2 만으로 유일성이 보장되지 않으면 쿼리 자체가 잘못된 것입니다.)
 
그리고 님께세 말씀하신대로 b 테이블의 인덱스 순서가 UNIQ_INDEX1, UNIQ_INDEX2,UNIQ_INDEX3으로 되어 있다면
머지 조인이 나타나는 것이 또한 이상합니다.
대부분은 NL 조인이 됩니다.
그리고 그런 경우 대부분 느리지 않습니다.
또한 드물게 HASH조인 OUTER를 유도해야 하는 경우가 있을 수 있습니다.
물론 아주 드물게 두 테이블이 조인이 필요없다고 옵티마이저가 판단하는 경우 머지 조인 카테시언이 나올 수 있기는 합니다만
이런 경우의 머지 조인은 옵티마이저가 제대로 판단한 것이라면 오히려 더 빨라지는 경우이므로 문제 되지 않습니다.
 
좀 두서없이 말씀드린 것 같은데요...
자세한 것은 알 수 없으나 둘 다 원하는 결과가 나온다면
실제로 둘 중 하나의 쿼리가 문제가 되는 상황이 아니면
두 쿼리는 거의 차이가 나지 않는 성능을 발휘하거나 차이가 있어도 무시할만하므로
더 편한 것을 쓰십시오(즉 일반적인 아우터를 쓰시면 됩니다.)
단 특별한 경우 문제가 되면 특별하게 튜닝을 하시면 될 것 같습니다.
 
김흥수(protokhs)님이 2015-08-24 17:15에 작성한 댓글입니다.

좋은 의견 감사합니다.

 

궁금이.님이 2015-08-24 18:16에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
40905문자열과 숫자 분리하기 [1]
개발자
2015-08-24
7970
40904union 문의 [2]
이현정
2015-08-24
7615
40903SQL UPDATE 질문입니다. [2]
22일
2015-08-22
8140
40902Plan결과 고수님 의견을 듣고 싶습니다. [4]
궁금이.
2015-08-21
7860
40901쿼리 질문입니다. [1]
ㅃㅃ
2015-08-21
7735
40900select for update에 관한 질문...
...
2015-08-20
7622
40899SUBSTR 질문입니다. [2]
이현정
2015-08-19
7666
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.022초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다