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 7947 게시물 읽기
No. 7947
like 로 검색 시 효율적인 방법은?
작성자
김대청(dcmru)
작성일
2009-06-16 13:56ⓒ
2009-06-16 14:15ⓜ
조회수
6,959

두 개의 테이블이 있습니다. 

하나의 테이블에는 유일한 값의 PK가 있고, 부수적인 컬럼들이 몇 개 있습니다.

다른 테이블에는 앞의 테이블의 PK와 같은 값으로 유일한 FK가 있고, 몇 개의 컬럼들이 있고, 하나의 컬럼에 단순히 문자열들이 들어갑니다.

table a (
      PK,
      ...,
      ...,
      ...,
)

table b (
      FK,
      ...,
      ...,
      ...,
      data varchar(256)
)

이 때 검색 시 두번째 테이블에서 data를 like 문으로 '%조건%" 검색을 한 FK와 첫 번째 테이블의 PK가 같은 것을 뽑아냅니다.

이 때 어떤 방법이 효율적일까요?

서브쿼리와 join으로 하니 속도가 느립니다. 단순히 쿼리 플랜을 보면 시퀀스 스캔을 하는것 같습니다.

Total runtime: 5852.805 ms 이정도 나옵니다.

두 번째 테이블의 데이타는 230만건정도입니다. 테스트용으로 만든것인데, 그렇게 많은 양이 아닙니다. 

많이 늘어날 수 있어서 속도가 더 느릴것 같습니다. 데이타 사용량만 몇십기가가 될 수 있습니다.


이 때 서브쿼리와 join을 할필요가 있나요? 두 테이블이 연결되는 것은 PK와 FK입니다.

단순히 FK만 뽑아서 PK를 검색을 하는것이 나을까요? 이렇게 하면 두 번의 쿼리를 해야합니다.

그리고 문자열 검색 시 빠른 검색을 위한 방법이 있나요? 문자열은 256길이의 varchar입니다.

이 컬럼에 인덱스를 걸어야할까요? 문자열인 컬럼을 인덱스를 걸면, 비효율적인가요?

하지만 검색 시 필요할것도 같구요. 조언부탁드립니다.

그리고 검색해 보니 % 사용 시 인덱스를 걸어도 인덱스를 안탈 수 있다고 나오던데요. 사실인가요?

그렇다면, 인덱스를 써도 효과가 없을것 같은데, 다른 방법이 있나요?


메인 질문과는 거리가 있는 질문인데 데이터를 문자열과 숫자로 저장할 수 있는데, 어떤 데이터가 효율적일까요? 

예를 들면 시간 데이터를 문자로 풀어서 저장할 수도 있고, 숫자로 저장할 수도 있는 경우입니다.

질문을 하다보니 질문이 많아진것 같습니다. ^^;

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

data like '%검색어%'


검색 방법은 당연히 인덱스를 사용하지 않습니다.


이 문제 때문에 각종 데이터베이스는 full text search 관련 기능을 제공합니다.


PostgreSQL에서는 tsearch 인가? 그 놈이 그 구실을 합니다.


자세한 것은 full text search 관련을 검색해 보시면 이곳에서 많이 논의하고 있습니다.

또 다른 검색어 하나가 tsearch2 입니다.

김상기(ioseph)님이 2009-06-16 16:12에 작성한 댓글입니다.

답글 감사드립니다. 다른 기능이 있었군요. 다시 검색모드로!! ^^

김대청(dcmru)님이 2009-06-16 17:00에 작성한 댓글입니다.
http://database.sarang.net/?inc=read&aid=5125&criteria=pgsql&subcrit=&id=&limit=20&keyword=tsearch&page=2 

이전 글을 보고, 적용해보았습니다.

vector 컬럼을 추가하고, 인덱스도 생성을 해보았는데, 
결과적으로는 like '%OO%' 보다 느립니다.
data는 일반 영문 명령어라고 생각하시면 됩니다.
vector 컬럼을 select 해보면, 단어별로 잘 들어가 있습니다. 
who 같은 명령어는 무시되었습니다. stop 설정관련 해서 그런것 같습니다.
gist 인덱스로 인해 실 데이타 크기도 두배정도 늘어났습니다.
원인이 무엇일까요? 데이터가 더많을 때 달라질까요?
그리고 y로 끝나는 단어는 i로 변경이 되어서 vector에 저장이 됩니다.
who가 생략되는 현상 등 설정을 더 해봐야겠습니다.

securedb=> explain analyze select sid from tableb where vector @@ to_tsquery('id');
                                                          QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on tableb  (cost=145.04..16121.82 rows=5132 width=82) (actual time=209.096..2364.629 rows=209794 loops=1)
   Filter: (vector @@ to_tsquery('id'::text))
   ->  Bitmap Index Scan on slidx17  (cost=0.00..143.75 rows=5132 width=0) (actual time=183.353..183.353 rows=209794 loops=1)
         Index Cond: (vector @@ to_tsquery('id'::text))
 Total runtime: 2569.485 ms
(5 rows)

securedb=> explain analyze select sid from tableb where data like '%id%';
                                                      QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
 Seq Scan on tableb  (cost=0.00..135502.80 rows=1026477 width=82) (actual time=28.378..2087.927 rows=209794 loops=1)
   Filter: ((data)::text ~~ '%id%'::text)
 Total runtime: 2237.611 ms
(3 rows)

securedb=> explain analyze select sid from tableb where data like 'id%';
                                                           QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on tableb  (cost=575.90..51871.93 rows=25662 width=82) (actual time=347.847..1826.707 rows=209794 loops=1)
   Filter: ((data)::text ~~ 'id%'::text)
   ->  Bitmap Index Scan on slidx16m  (cost=0.00..569.49 rows=25662 width=0) (actual time=250.318..250.318 rows=419588 loops=1)
         Index Cond: (((data)::text >= 'id'::text) AND ((data)::text < 'ie'::text))
 Total runtime: 1977.086 ms
(5 rows)

a테이블과 조인을 하여 distinct를 덧붙여 쿼리하였을 때는 반대의 현상이 나타나는군요. tsearch2를 적용하여 쿼리하였을때 4.3초 적용안하였을 때 6.3초 정도 나옵니다. 사이즈는 배로 늘었는데, 괄목할만한 향상이 보이지는 않습니다...

김대청(dcmru)님이 2009-06-17 18:32에 작성한 댓글입니다.
이 댓글은 2009-06-17 19:01에 마지막으로 수정되었습니다.
[Top]
No.
제목
작성자
작성일
조회
7956저기.. 작업시간.. [6]
ff
2009-06-18
6310
7953PostgreSQL 8.4 RC1 떴네요; [5]
김병길
2009-06-17
6275
7948DB Table Backup 오류 [4]
궁굼이
2009-06-16
9191
7947like 로 검색 시 효율적인 방법은? [3]
김대청
2009-06-16
6959
7946디비 필드수가 검색기능에 어느정도 영향을 끼치는지 궁금합니다 [2]
초보
2009-06-16
6106
7945게시판 번호를 max+1 할때... [4]
안녕하세요`
2009-06-15
6946
7942Trigger 비슷한 기능을 구현하는데요... [1]
아즈샤라
2009-06-15
6130
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.018초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다