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
운영게시판
최근게시물
PostgreSQL Q&A 10161 게시물 읽기
No. 10161
실행계획 제가 읽는 방법이 맞는지 알려주세요...
작성자
신은정(sin4640)
작성일
2020-06-08 16:32ⓒ
2020-06-08 16:42ⓜ
조회수
208
 
 
안녕하세요. PostgreSQL 입문한지 얼마되지 않았고 Explain 부분 공부하는 중 이해가 안가는 부분이 있어 초보적인 질문인걸 알면서도 질문드립니다 ㅠ 
 
 
 
 
create table t1 (c1 integer, dummy char(1000));
create table t2 (c1 integer, dummy char(1000));
create table t3 (c1 integer, dummy char(1000));
 
 
insert into t1 select generate_series(1,10), 'dummy';
insert into t2 select generate_series(1,1000), 'dummy';
insert into t3 select generate_series(1,10000), 'dummy';
 
create index t2_idx01 on t2(c1);
create index t3_idx01 on t3(c1);
 
select *
 from t1 a, t2 b, t3 c
where a.c1 = b.c1
    and b.c1 = c.c1 ;
 
 
Nested Loop  (cost=0.56..84.87 rows=10 width=3024)
  Join Filter: (a.c1 = b.c1)
  ->  Nested Loop  (cost=0.29..81.22 rows=10 width=2016)
        ->  Seq Scan on t1 a  (cost=0.00..2.10 rows=10 width=1008)
        ->  Index Scan using t3_idx01 on t3 c  (cost=0.29..7.90 rows=1 width=1008)
               Index Cond: (c1 = a.c1)
  ->  Index Scan using t2_idx01 on t2 b  (cost=0.28..0.35 rows=1 width=1008)
         Index Cond: (c1 = c.c1)
 
 
 
 
==============================================================================
 
 
 
 
위에 실행계획을 제가 이해한 바로는   t3_idx01 인덱스를 읽어서 t1 테이블과 Nested 조인한 결과와 t2_idx01 인덱스를 읽은 후 의 결과와 Nested 조인하는게 맞는건가요?
 
 
 
 
그리고
 
->  Nested Loop  (cost=0.29..81.22 rows=10 width=2016)
        ->  Seq Scan on t1 a  (cost=0.00..2.10 rows=10 width=1008)
        ->  Index Scan using t3_idx01 on t3 c  (cost=0.29..7.90 rows=1 width=1008)
               Index Cond: (c1 = a.c1)
 
SQL에서는 where 절에서 a.c1 = b.c1 조건으로 비교하였는데 위에 처럼
 
 
 
 t3_idx01 인덱스 결과와 t1 테이블과 왜 조인하는지 모르겠습니다.ㅠ
 
 
 
 
 
 
 
 
이 글에 대한 댓글이 총 3건 있습니다.

실행 순서입니다. 

1) t1 풀스캔(seq scan) 
2) t3 인덱스 스캔( t3_idx01) 
3) nl 조인(t1, t3) 
4) t2 인덱스 스캔( t2_idx01) 
5) nl조인( 3)의 결과와 t2 )  

조인 순서는 
t1 --> t3 --> t2 

드라이빙 테이블은 t1 입니다.

nl 조인의 경우 오라클과 동일하지만, 

hash 조인의 경우는 오라클과 해석법이 틀립니다. (반대임) 

 

lucky님이 2020-06-09 10:38에 작성한 댓글입니다.
이 댓글은 2020-06-09 10:38에 마지막으로 수정되었습니다. Edit

 t1이랑 t2가 먼저 만나서 그 결과를 가지고, t3에서 찾을 수도 있어요. 

그런데, 여기서는 t1이랑 t3가 먼저 만났네요. 

이유는 실행계획기만 알겠죠. 

보통 이렇게 사람의 상식과 다르게 계획을 짤때는 그 나름의 이유가 있어서입니다. 

이유가 없다면, 정말 그 때 그때의 운이기도 하고요. 

 

그 나름의 이유는 대부분 해당 테이블의 자료분포를 저장하는 통계정보 때문입니다. 

generate_series 함수를 이용해서 자료를 입력한 뒤, 정상적으로 해당 테이블의 통계정보를 수집했다면, 

모든 테이블의 c1 칼럼에 대한 자료 분포는 아주 고르다고 판단하겠죠. 

이런경우라는 c1,c2 를 join 비용이나, c1, c3 join 비용이나 다 같겠네요. 

그런데, 무슨 이유에 의해서인지는 모르겠지만, pg의 최적화기는 c1, c3 를 먼저 선택했네요. 

아마도 다중 join 에서 이런 방식 (처음과 끝 테이블을 먼저 처리한다)이 보다 합리적인 방식이다고 판단한 것 같습니다. 

 

옵티마이져 짠 사람에게 물어봐야 정확한 설명을 들을 수 있을 것 같습니다. 

 

여튼 실세계내에 정말 저런 형태의 자료라면 저라면, t2_idx01 인덱스를 없애, t1,t2를 해시로 만들고 그걸 t3의 nested로 풀것 같습니다. 

그렇게 하면, 아마 최적화는 t1,t3 nested를 먼저하고, 그걸로 t2랑 해시 조인을 할 수도 있겠군요. 안해봐서 모르겠습니다.

김상기(ioseph)님이 2020-06-09 13:22에 작성한 댓글입니다.

pgadmin 툴을 사용하신다면

F7 누르시고 하단의 EXPLAIN 탭에서 첫번째 Graphical  을 보시면 시각적으로 표현해 줍니다.

천정대(gt1000)님이 2020-06-11 10:09에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
10165ecpg의 메모리 누수 문제 관련으로 문의드립니다. [2]
정상규
2020-06-18
105
10164restore중 오류, exit code-6이 발생합니다. [2]
박 우현
2020-06-18
96
10163pg_basebackup 백업/복원 방법 [3]
ㅇㅇ
2020-06-17
140
10161실행계획 제가 읽는 방법이 맞는지 알려주세요... [3]
신은정
2020-06-08
208
10160스트링인데 길이가 조사되지 않네요. [1]
JungHo Kim
2020-06-05
138
10158pg_archivecleanup 은 어떻게 수행하세요? [1]
.test
2020-05-13
188
10157Postgresql의 프로시저에서 cursor 리턴에 대한 mybatis쪽의 정의는 어떻게 되나요? [1]
권오준
2020-05-06
253
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2019 DSN, All rights reserved.
작업시간: 0.070초, 이곳 서비스는
	PostgreSQL v11.5로 자료를 관리합니다