안녕하십니까 ^^;
맨날 도움만 받아가다가 저도 드디어 도움이 될만한 기회가..
사실 도움이 되겠다기 보다는 제가 도움받은 내용을 적으려고 합니다 -_-;;
제가 PostgreSQL을 쓰는 가장 큰 이유중에 하나는 배열 컬럼의 지원입니다.
그동안 배열컬럼을 쓰면서 배열요소에 대한 검색이 필요 없었어서 배열요소에 대한 인덱스를 전혀 고려하지 않았었는데 갑자기 검색할 일이 생겼습죠.
그래서 자료실의 김상기님의 1차원배열에 관한 함수를 조금 수정해서 arr_join 이라는 함수를 만들었습니다. 단순하게 배열의 요소들을 텍스트 문자열로 붙여서 리턴하게 하는 함수였습니다.
사용할때는 arr_join(배열컬럼) like '%,검색값%' 이렇게 했습니다.
당연히 좋지도 않은 방법이고 시간도 오래걸렸습니다.
이곳에 질문을 올렸더니 많은 분들이 도움을 주셨는데..
그중에 배열데이터 타입을 검색하는 *= 연산자와 배열데이터에 GIST방식으로 인덱싱 하여 @@ 연산자로 검색하는 방법이 있었습니다.
일단 *= 연산자에 대한 설명입니다.
테스트 환경은 7.2.3 컴파일 버전과 7.2.1 RPM버전입니다.
RPM 버전 : /usr/lib/pgsql/contrib/array
소스 버전 : 소스/contrib/array
위의 경로로 이동합니다.
이곳에 가시면 array_iterator 에 관련된 파일이 있습니다.
우선 리드미 파일은 각자 읽어보시구요 =_=
RPM 버전
# psql 데이터베이스
데이터베이스=# \i array_iterator.sql
소스 버전
# make
# cp array_iterator.so pgsql이설치된경로/lib/
# psql 데이터베이스
데이터베이스=# \i array_iterator.sql
해주시면 끝입니다
이제 *= 연산자를 사용하실수 있습니다.
데이터베이스=# select * from TEST where 배열커럼 *= 검색값 ;
이제 저처럼 무식하게 낭비가 심한 펑션을 만들거나 검색을 하실 필요가 없습니다 -_-;; 제가 처음에 했던 방식보다 거의 20배 빠르더군요 -_-;
그리고 유용한 연산자 *~ 같은 경우는 where 배열컬럼 *~ '검색값'
하게 되면 검색값을 포함되는 배열요소를 다 찾아냅니다. 꽤 유용할듯 싶습니다 ^^;
약간의 욕심이 더 생겼습니다 -_-;
제 질문의 답변 가운데 intarray로 정수형 배열에 대한 인덱싱에 관련된 언급이 있었는데 이곳을 잘 찾아보시면 찾으실수 있습니다. 간단하게 말씀드리면
위와 비슷한 방식입니다.
RPM 버전 : /usr/lib/pgsql/contrib/intarray
소스 버전 : 소스/contrib/intarray
RPM 버전
# psql 데이터베이스
데이터베이스=# \i _int.sql
소스 버전
# make
# cp _int.so pgsql이설치된경로/lib/
# psql 데이터베이스
데이터베이스=# \i _int.sql
역시.. 간단하게 끝입니다.
저렇게 하면 GIST인덱스와 @@, ~~ 등 몇개의 연산자가 생깁니다
자세한 내용은 리드미나 _int.sql을 보시면 되구요~
제가 예제로 보여드릴 연산자는 @@ 입니다.
그 전에 인덱스를 생성하셔야 하구요
데이터베이스=# CREATE INDEX TEST_배열컬럼 ON TEST USING GIST (배열컬럼);
데이터베이스=# select * from TEST where 배열커럼 @@ '검색값' ;
인덱스 사용여부는 EXPLAIN으로 해보시면 됩니다.
제가 테스트해본 결과로는 *=의 60~70%정도의 시간만 소요됐습니다 :)
주의하실 점이라면
where 배열컬럼 *= '1111' (O)
where 배열컬럼 *= 1111 (O)
where 배열컬럼 @@ '1111' (O)
where 배열컬럼 @@ 1111 (X) <- @@ 쓰실때는 꼭 ' 로 감싸주시길 -_-;
안그럼 에러가 납니다~
그럼.. 도움이 되길바랍니다 =3=3=3
|