SQL문 만들때 like 연산을 많이 사용합니다. 데이터가 정확히 일치하지 않아서 like '%...%' 형태로 조회해야 하는 경우가 많기 때문이죠~
하지만, 이 like SQL문에서 검색문자열 앞에 % 가 있는 경우에는 인덱스를 타지 않거나, Index Fast Full Scan 을 하게 됩니다. 인덱스를 통째로 읽어서 찾는 겁니다. Tabel Full Scan 과 비슷합니다. 따라서 많이 느리겠죠~~
ex) where A like '%노을'
이런 경우에, 빠르게 할 수 있는 방법이 있습니다.
바로 "Oracle Text" 라는 기능입니다. 예전에는 Intermedia Text 라고 불렸었습니다.
또는 Domain Index 라고 부르는 사람도 있고, Text Index 라고 부르는 사람도 있습니다. 모두 같은 겁니다.^^
이 기능을 사용하게 되면 내부적으로 키워드 딕셔너리를 구성합니다. 그래서 키워드 테이블에서 검색해오기 때문에 매우 빠릅니다.
하지만, 사용자는 마치 일반 인덱스(Index) 만들듯이 만들면 되고, 모든 필요한 작업들은 Oracle DBMS 가 알아서 자동으로 해 줍니다.
11g 이상의 DB에 보면 Oracle Text 가 디폴트로 설치되어 있습니다. 그래서 별도로 설치할 필요가 없습니다.
위와 같이 조회해봐서 STATUS 가 VALID 로 나오면 사용할 수 있습니다.
DBA_USERS 딕셔너리를 조회해보면 CTXSYS 라는 DB 유저가 보이는데, 이게 이 Oracle Text 와 관련된 기능을 수행하기 위한 DB 유저입니다.
그럼, 한번 Oracle Text 기능이 얼마나 빠른지 확인해 볼까요??
먼저, 아래와 같이 테스트를 위한 테이블과 데이터를 생성합니다.
-- 테스트 테이블 T1 생성
create table T1 (
line number,
text varchar2(4000)
);
-- 테스트 데이터 입력
insert into T1 values ( 1, '붉게 물든 노을 바라보면 슬픈 그대 얼굴 생각이나');
insert into T1 values ( 2, '고개 숙이네 눈물 흘러 아무 말 할 수가 없지만');
insert into T1 values ( 3, '난 너를 사랑하네 이 세상은 너 뿐이야 소리쳐 부르지만');
insert into T1 values ( 4, '저 대답 없는 노을만 붉게 타는데');
insert into T1 values ( 5, '그 세월 속에 잊어야할 기억들이 다시 생각나면');
insert into T1 values ( 6, '눈감아요 소리 없이 그 이름 불러요');
insert into T1 values ( 7, '아름다웠던 그대모습 다시 볼 수 없는 것 알아요');
insert into T1 values ( 8, '후회 없어 저 타는 노을 붉은 노을처럼');
insert into T1 values ( 9, '난 너를 사랑하네 이 세상은 너 뿐이야 소리쳐 부르지만');
insert into T1 values (10, '저 대답 없는 노을만 붉게 타는데');
insert into T1 values (11, '어디로 갔을까 사랑하던 슬픈 그대 얼굴 보고싶어');
insert into T1 values (12, '깊은 사랑 후회 없어 저 타는 붉은 노을처럼');
insert into T1 values (13, '난 너를 사랑하네 이 세상은 너 뿐이야 소리쳐 부르지만');
insert into T1 values (14, '저 대답 없는 노을만 붉게 타는데');
insert into T1 values (15, '그 세월 속에 잊어야할 기억들이 다시 생각나면 눈감아요…');
insert /*+ parallel(4) */ into T1 select * from T1;
--> 데이터 증식을 위해 이거 20번 반복 (15,728,640 건)
-- 테스트 테이블 T2 생성
create table T2 as select * from T1;
좀더, 극적인 연출을 위해^^ 데이터를 좀 크게 증식해서 만들었습니다. 약 1천5백만건. 너무 큰가 ^^;
성능 비교 검증을 위해 T2 테이블을 생성합니다.
T2 테이블은 T1 테이블을 복제해서 똑같이 만들어 줬습니다.
T1, T2 테이블에 인덱스를 만들어줍니다.
-- 테이블 T1 에 인덱스 생성 (Oracle Text 기능 사용)
create index T1_IDX1 on T1(text) indextype is ctxsys.context;
-- 테이블 T2 에 인덱스 생성 (일반 인덱스)
create index T2_IDX1 on T2(text);
T1 테이블에는 Oracle Text 인덱스를 T2 테이블에는 일반 인덱스를 생성합니다.
데이터가 많으니 인덱스 생성 작업도 좀 오래 걸립니다. 빠르게 하려면 둘다 뒤에 parallel(10) 와 같이 병렬처리 옵션을 커맨드 맨뒤에 붙여주기만 하면 됩니다.
자~ 이제 준비끝~~~
함 테스트 해볼까요???
-- 일반 like 문으로 조회
select count(*) from T2 where text like '%아름다웠%';
-- Oracle Text 방식으로 조회
select count(*) from T1 where CONTAINS (text, '%아름다웠%') > 0;
Oracle Text 에서는 contains( ) 라는 함수를 사용하는게 좀 다릅니다. 하지만, 키워드 앞뒤로 % 붙이는 것은 같습니다.
So, 결과는???
와우, Oracle Text 의 경우는 0.28초, 일반 Index 의 경우는 3.61초 걸렸네요.
12배 정도 차이가 나네요^^ 와우~ 쓸만한데요~~
((공정한 테스트를 위해 둘다 여러번 실행해서 버퍼캐시에 캐싱되도록 한 결과입니다.))
혹, Index 생성/삭제 중에 에러가 발생하면 아래 참조하세요.
>> Oracle Text 인덱스 생성/삭제시 Error ORA-29855, ORA-20000, DRG-50857, DRG-10502, DRG-10507
이것도 참고요
>> Oracle Text Index 관리할때 주의사항
'IT관련' 카테고리의 다른 글
Oracle Text 인덱스 생성/삭제시 Error ORA-29855, ORA-20000, DRG-50857, DRG-10502, DRG-10507 (0) | 2019.12.18 |
---|---|
오라클 SQL문에서 like 문 처리 샘플 ( %, _ ) (0) | 2019.12.13 |
오라클 PK(Primary Key), FK(Foreign Key) 예제 (0) | 2019.12.12 |
(12cR1 신기능) 오라클 Scalar Subquery Unnesting (_optimizer_unnest_scalar_sq) (0) | 2019.12.11 |
Oracle 무료 DB관리툴 ((EM Express)) - 포트변경, http 로 접속 설정 방법 (0) | 2019.12.11 |