# Full Text search



여러분이 게시판 서비스를 운영한다고 칩시다.

그래서 테이블 하나에 게시물의 글내용, 작성자, 발행일을 저장하기 시작했는데 &#x20;

검색기능이 필요해진겁니다. 검색기능은 어떻게 구현하죠?&#x20;

&#x20;



### **LIKE 연산자**



예전에 간단한 검색기능 만들고 싶으면 **컬럼명 LIKE %단어%** 하면 된다고 했습니다.

짧은 문장 안에서 검색하는건 이걸로 충분하지만&#x20;

1\. % 기호를 맨 앞에 쓰면 인덱스활용을 못하고

2\. 문장이 좀 길거나 행이 너무 많아지면 LIKE 만으로는 매우 느리게 동작합니다.

하지만 full text index를 만들어두면 걱정없습니다.&#x20;



### **Full text search를 위한 index**



긴 글도 데이터베이스의 컬럼 하나에 보관할 수 있습니다.&#x20;

text 데이터타입 쓰면 6만5천자를 보관할 수 있으니까요.&#x20;

이렇게 긴 글 안에서 원하는 단어를 검색하고 싶다면 당연히 index를 만들어두어야 검색이 빨라집니다.

근데 긴 글은 그냥 index 말고 full text search index를 만들어두면 됩니다.&#x20;





궁금할까봐 어떤 원리로 index를 만들어주는지 설명하자면



<table><thead><tr><th width="182">id</th><th>글</th></tr></thead><tbody><tr><td>1</td><td>I run regularly.</td></tr><tr><td>2</td><td>I eat breakfast.</td></tr><tr><td>3</td><td>I like running.</td></tr><tr><td>4</td><td>I like eating pizza.</td></tr><tr><td>5</td><td>I swim in the sea.</td></tr></tbody></table>

이런 테이블이 있다고 칩시다.&#x20;

이 테이블에 full text index를 만들라고 시키면&#x20;

&#x20;

<table data-header-hidden><thead><tr><th width="274"></th><th></th></tr></thead><tbody><tr><td><strong>단어</strong></td><td><strong>어떤 행에 나오냐면</strong></td></tr><tr><td>eat</td><td>2, 4</td></tr><tr><td>run</td><td>1, 3</td></tr><tr><td>swim</td><td>5</td></tr></tbody></table>



긴 글에 있는 모든 단어를 뽑아서 정렬해주고&#x20;

그 단어가 어떤 행에 출몰중인지를 옆에 적어둡니다.&#x20;

이러면 eat 이런 단어를 검색했을 때 어떤 행에 들어있는지 쉽게 파악가능하겠죠?

이게 끝입니다.



근데 문장 안에서 stopwords라고 부르는

"is the a are and I" 등 내용과 상관없는 쓸데없는 단어들을 제거하고 index를 만드는 경우가 많습니다.

그래서 웹의 검색엔진들이 is the a are 이런 내용 붙여서 검색하면 대부분 무시하는 이유가 그겁니다.&#x20;





### **Full text index 만드는 법**



```sql
CREATE INDEX LIB_IDX_TEXT ON TEST.LIBRARY (서명)
indextype is ctxsys.context;
```



### Index 성능 평가&#x20;



#### &#x20;1. LIKE 검색 시 성능



<figure><img src="https://3814826491-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJyHOwztPxBT3bLpisjCt%2Fuploads%2FIMZOLMBeK1Cherbrf8PH%2FScreenshot_70.png?alt=media&#x26;token=f866306d-69ea-413b-b8c2-f8265ebd542c" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3814826491-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJyHOwztPxBT3bLpisjCt%2Fuploads%2FWu9FmgXYsgT2GgpjsCDC%2FScreenshot_71.png?alt=media&#x26;token=fbd81500-3db1-42c4-9a99-156e06324e5e" alt=""><figcaption></figcaption></figure>

#### &#x20;2. CONTAINS 검색 시 성능

<figure><img src="https://3814826491-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJyHOwztPxBT3bLpisjCt%2Fuploads%2F3uFIuqa6ujmPEHxF2hIv%2FScreenshot_73.png?alt=media&#x26;token=2bb75ad7-8bef-4b71-9447-7a70f79a81f6" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3814826491-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJyHOwztPxBT3bLpisjCt%2Fuploads%2FTPA6UtmXkMEp8TGVftqh%2FScreenshot_72.png?alt=media&#x26;token=b150b5d1-e4e2-4b30-93b9-2a22d891d364" alt=""><figcaption></figcaption></figure>



### **Full text index를 이용해 검색하려면**



WHERE 뒤에 조건식 형태로 CONTAINS(컬럼명 , '%찾을단어%') > 0 이런식으로 사용합니다.



```sql
SELECT *
  FROM LIBRARY l 
 WHERE CONTAINS(서명, '%부동산%') > 0;
```

이렇게 작성해서 실행해봅시다.

그럼 '부동산' 이라는 정확한 단어를 가진 행을 매우 빠르게 필터링해줍니다.

진짜 빠른지 확인하려면 execution plan 눌러봅시다.







Oracle Text 관리할 때 주의사항

{% embed url="https://jack-of-all-trades.tistory.com/250" %}





\- 이 정도의 성능 말고 네이버, 구글, 대형쇼핑몰처럼 검색성능이 아주 중요한 사이트를 만들고 있다면&#x20;

elastic search라든지 검색만을 위한 DB 또는 서비스를 따로 사용할 수도 있기 때문에 그걸 쓰는게 나을 수 있습니다.&#x20;

\- 다른 DBMS는 다른 문법이나 방법을 사용하는 경우가 많아서 필요 시 따로 검색해봅시다.&#x20;



(참고)

Oracle Text를예전에는 Intermedia Text 라고 불렸었습니다.

또는 Domain Index 라고 부르는 사람도 있고, Text Index 라고 부르는 사람도 있습니다.

모두 같은 겁니다.

