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 8919 게시물 읽기
No. 8919
index를 이용한 정렬
작성자
facy(애송이)
작성일
2011-12-26 21:39
조회수
11,720

order by 구문을 사용하지 않고 정렬을 하기 위해 index를 이용했습니다.

아래는 제가 테스트한 몇가지 방법과 궁금한 점을 써놓았습니다.

 

create table test(

name varchar(10)

, constraint pk_test primary key (test)

);

 

insert into test values ('aaa');

insert into test values ('ccc');

insert into test values ('bbb');

 

# 얻고자 하는 답은 실행계획에서 Sort 부분이 없이 데이터가 정렬이 되어서 나오는 것입니다.

- 첫번재 방법

explain analyze select * from test where name > '';

"Bitmap Heap Scan on test (cost=7.35..22.35 rows=400 width=38) (actual time=0.031..0.031 rows=3 loops=1)"
" Recheck Cond: ((name)::text > ''::text)"
" -> Bitmap Index Scan on pk_test (cost=0.00..7.25 rows=400 width=0) (actual time=0.023..0.023 rows=3 loops=1)"
" Index Cond: ((name)::text > ''::text)"
"Total runtime: 0.082 ms"
 

하지만 bitmap index scan이 일어나면서 정렬이 되지 않았습니다.

 

- 두번째 방법

explain analyze select * from test where name > '' order by name;

"Sort (cost=39.64..40.64 rows=400 width=38) (actual time=0.063..0.064 rows=3 loops=1)"
" Sort Key: name"
" Sort Method: quicksort Memory: 25kB"
" -> Bitmap Heap Scan on test (cost=7.35..22.35 rows=400 width=38) (actual time=0.042..0.043 rows=3 loops=1)"
" Recheck Cond: ((name)::text > ''::text)"
" -> Bitmap Index Scan on pk_test (cost=0.00..7.25 rows=400 width=0) (actual time=0.033..0.033 rows=3 loops=1)"
" Index Cond: ((name)::text > ''::text)"
"Total runtime: 0.112 ms"
 

이것도 역시 bitmap index scan이 발생했고, quicksort 까지 나타났습니다.

 

- 세번째 방법

set enable_bitmapscan = off;
set enable_seqscan = off;

explain analyze select * from test where name > '';

"Index Scan using pk_test on test (cost=0.00..51.25 rows=400 width=38) (actual time=0.027..0.030 rows=3 loops=1)"
" Index Cond: ((name)::text > ''::text)"
"Total runtime: 0.066 ms"
 

이제야 제가 원하는 답이 나왔습니다. cost가 살짝 더 나오긴 했지만 실행시간은 가장 짧았습니다.

 

여기서 제가 궁금한것은

set enable_bitmapscan = off;
set enable_seqscan = off;

질문 1. 옵션 조정없이 bitmap index scan을 타지않고 index scan으로 실행계획을 변경할 수 있느냐?

질문 2. bitmap index scan과 index scan은 어떻게 다른가?

알고 계시는 분이 있으시다면 알려주세요.

겨우겨우 삽질해가면서 여기까지 왔습니다.

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

 비트맵 스캔이 일반 인덱스 스캔보다 비용이 적게 드니까, 

최적화기는 비트맵을 선택하겠죠. 

PostgreSQL의 쿼리 최적화기는 비용기반으로 제일 적게 드는 비용을 선택하게 되어있습니다. 

일반적으로 정렬이나, nested loop 같이 출력 전 내부적으로 자료를 한 번 더 가공해야할 경우,

그 자료량이 메모리 용량(정확하게 work memory 가 아닐까싶네요) 에서 충분히 처리 할 수 있다면, 

당연히 인덱스 스캔보다는 비트맵 스캔을 이용하는 것이 

이론상으로는 낫겠죠. 

 

김상기(ioseph)님이 2011-12-27 10:31에 작성한 댓글입니다.

음.. 그렇다면,

index scan이 비용이 더 적게 드는 상황이 되어야만 최적화기가 index scan을 실행계획으로 선택하겠네요.

PostgreSQL도 오라클 처럼 힌트가 있다면index를 이용한 정렬을 할 수 있을텐데.

아무래도 옵션설정을 조정하는 방법만이 강제로 index scan을 하게 하는 방법이겠네요.

facy(애송이)님이 2011-12-27 18:15에 작성한 댓글입니다.

세번째 방법처럼 세션 단위로, 해당 쿼리를 실행 하기 전 쿼리최적화기가  실행계획수립을 수립할 방법을 강제로 매번 조정하는 방법도 있겠고,

 EnterpriseDB 라는 상용 PostgreSQL 서버가 있습니다. 

그놈이 오라클 호환성이 비교적(?) 좋아 오라클 기반 서비스를 PostgreSQL 서비스로 마이그레이션 하는데, 유용하게 쓰이기도 합니다.

이 DB가 오라클처럼 인덱스 힌트를 쓰기도 합니다.

 

김상기(ioseph)님이 2011-12-28 09:15에 작성한 댓글입니다.

질문하신것과는 조금 다른내용인데요.

where조건없이 order by절을 사용해도 인덱스를 이용해서 sort작업을 하지 않는게 유리하다고 판단되면 인덱스스캔으로 풀립니다. 즉 원하시는 결과가 정렬된 결과일떄는 반드시 order by절을 사용하셔야됩니다.

판단은 옵티마이저가 하는것이고 옵티마이저가 비효율적인 실행계획을 선택할수도 있지만 order by절 유무와는 상관없는는거죠.

테스트하신대로 설정값변경으로 힌트처럼 사용하실수도 있지만 서비스환경에서 실행계획을 강제하는건 부정적인부분이 더 많을듯하네요.

백수환(back17)님이 2011-12-28 13:53에 작성한 댓글입니다.

 결국엔 옵티마이저를 믿고 쓰되,

적절하게 통계 데이터를 갱신해줘야겠군요.

facy(애송이)님이 2011-12-28 15:25에 작성한 댓글입니다.

cost계산에 사용되는 설정값들을 서비스특성에 따라 최적화 해주고 통계정보는 중요한역활을 하는 컬럼들은 target_statistics 값을 지정해주는식으로 어느정도 최적화를 유도?할수 있을듯 합니다.

백수환(back17)님이 2011-12-28 16:45에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
8922bitmap index scan 질문 [2]
facy
2011-12-28
8701
8921psql \set 명령어
김상기
2011-12-28
8672
8920컬럼 타입 변환 관련 질문입니다. [1]
이종복
2011-12-27
7936
8919index를 이용한 정렬 [6]
facy
2011-12-26
11720
8917Numeric 관련 질문드립니다. [1]
이종복
2011-12-26
8095
8916한글 관련 문제 [7]
이효광
2011-12-21
14813
8915DB와 Tomcat 운영 문의 사항 [2]
박병훈
2011-12-21
8814
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.028초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다