pg_trgm 설치하기

POSTGRESQL 2014. 10. 26. 18:48
postgresql 추가모듈 중 pg_trgm을 이용하여 '%문자열%' like 검색시 인덱스 스캔을 실행할 수 있습니다.

설치하기 전의 옵티마이저는 아래와 같이 full scan 메소드를 선택합니다.
testdb=# explain analyze select * from test_table where test_column like '%TEXT%';
                                                     QUERY PLAN                                                      
---------------------------------------------------------------------------------------------------------------------
 Seq Scan on test_table  (cost=0.00..288431.08 rows=264 width=298) (actual time=952.905..1119.831 rows=6 loops=1)
   Filter: ((test_column)::text ~~ '%TEXT%'::text)
 Total runtime: 1119.854 ms
(3 rows)


위와 같은 경우의 인덱싱 지원을 위해
1. contrib모듈을 설치합니다.
$ make
$ make install


2. 해당 데이터베이스에 extension을 생성합니다.
testdb=# create extension pg_trgm;
CREATE EXTENSION
CREATE INDEX trgm_idx ON test_table USING gin (test_column gin_trgm_ops);
CREATE INDEX


설치 이후 동일한 SQL에 대하여 index scan 메소드가 선택된 것을 확인할 수 있었습니다.
testdb=# explain analyze select * from test_table where test_column like '%TEXT%';
                                                      QUERY PLAN                                                       
-----------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on test_table  (cost=22.42..1245.43 rows=313 width=298) (actual time=0.021..0.029 rows=6 loops=1)
   Recheck Cond: ((test_column)::text ~~ '%TEXT%'::text)
   ->  Bitmap Index Scan on trgm_idx  (cost=0.00..22.35 rows=313 width=0) (actual time=0.014..0.014 rows=6 loops=1)
         Index Cond: ((test_column)::text ~~ '%TEXT%'::text)
 Total runtime: 0.051 ms
(5 rows)


※제약사항 : 3글자 미만에 대한 패턴검색의 경우 인덱스 탐색비용이 급격히 증가, table full scan의 비용을 초과함.

'POSTGRESQL' 카테고리의 다른 글

max_connections 와 커널파라메터  (0) 2014.10.27
postgresql DBLINK 예제  (0) 2014.10.27
gdb로 postgresql backend process 디버깅하기  (0) 2014.10.26
table/index bloat 점검하기  (0) 2014.10.26
prepare statements 와 casting  (0) 2014.10.26

특정 디렉토리를 사용하는 프로세스 확인(lsof)

LINUX 2014. 10. 26. 18:25

디스크 언마운트 시도 시 현재 사용중인 디스크에 대해 언마운트 할 수 없을 경우 해당 디스크를 점유중인 프로세스를 확인할 수 있습니다.

# umount /directory
umount: /directory: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))

lsof 명령어를 이용하여 해당 해당 디스크를 점유중인 프로세스를 확인합니다.
# lsof +D /directory
COMMAND    PID     USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
bash          10479 postgres  cwd    DIR    8,4     8192 16056321 /directory/postDATA/DATA/pg_log
psql              20824 postgres  cwd    DIR    8,4     4096 15974401 /directory/postDATA/DATA
postgres        21635 postgres  cwd    DIR    8,4     4096 15974401 /directory/postDATA/DATA
postgres        21636 postgres  cwd    DIR    8,4     4096 15974401 /directory/postDATA/DATA
postgres        21636 postgres    8w   REG    8,4     1072 16056322 /directory/postDATA/DATA/pg_log/postgresql-2013-02-25_142559.log


prepare statements 와 casting

POSTGRESQL 2014. 10. 26. 18:12

타 DB에서 운영하던 prepare statement를 postgreSQL로 포팅이후 못보던 오류(주로 서로다른 타입에 대한 operator가 없다는 등의)를 경험하게 되는데요. 이는 postgresql에서 parepare 구문을 이용하여 바인드변수로 SQL을 실행할때 묵시적형변환을 지원하지 않기 때문입니다.



먼저 일반적인 경우라면 아래와 같이 자동형변환을 확인할 수 있지만...

test=# create table test_table(col1 numeric);
CREATE TABLE
test=# insert into test_table values(1);
INSERT 0 1
test=# explain select col1 from test_table where col1 = '1';
                                  QUERY PLAN                                   
-------------------------------------------------------------------------
 Seq Scan on test_table  (cost=10000000000.00..10000000026.38 rows=7 width=32)
   Filter: (col1 = 1::numeric)
(2 rows)


바인딩변수를 이용하여 실행해 보면 numeric 타입과 varchar 타입간의 = operator를 찾을 수없다는 오류가 발생합니다.
test=# prepare foo(varchar) as
test-# select col1 from test_table where col1 = $1;
ERROR:  operator does not exist: numeric = character varying
LINE 2: select col1 from test_table where col1 = $1;
                                               ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
test=# 


이는 형변환을 명시함으로써 해결할 수 있습니다.
test=# prepare foo(varchar) as
select col1 from test_table where col1 = $1::numeric;
PREPARE
test=# execute foo('1');
 col1 
------
    1
(1 row)


'POSTGRESQL' 카테고리의 다른 글

max_connections 와 커널파라메터  (0) 2014.10.27
postgresql DBLINK 예제  (0) 2014.10.27
gdb로 postgresql backend process 디버깅하기  (0) 2014.10.26
table/index bloat 점검하기  (0) 2014.10.26
pg_trgm 설치하기  (1) 2014.10.26