전체 텍스트 인덱스 구조
전체 텍스트 인덱스의 구조를 잘 알게 되면 전체 텍스트 엔진의 작동 원리를 이해하는 데 도움이 됩니다. 이 항목에서 예제 테이블로 사용하는 테이블은 Adventure Works의 Document 테이블에서 발췌한 것입니다. 이 테이블에는 DocumentID 열 및 Title 열의 2개 열과 테이블의 3개 행만 표시됩니다.
이 예에서는 Title 열에 대해 전체 텍스트 인덱스를 만들었다고 가정합니다.
DocumentID |
Title |
---|---|
1 |
Crank Arm and Tire Maintenance |
2 |
Front Reflector Bracket and Reflector Assembly 3 |
3 |
Front Reflector Bracket Installation |
예를 들어 조각 1을 보여 주는 아래 표에서는 Document 테이블의 Title 열에 생성된 전체 텍스트 인덱스의 내용을 설명합니다. 전체 텍스트 인덱스에는 이 표에 표시되어 있는 것보다 많은 정보가 포함되어 있습니다. 이 표는 전체 텍스트 인덱스를 논리적으로 표현한 것이며 설명 목적으로만 제공됩니다. 행은 디스크 사용률을 최적화하기 위해 압축된 형식으로 저장됩니다.
데이터는 원래 문서와 다르게 반전되었습니다. 왜냐하면 키워드가 문서 ID로 매핑되기 때문입니다. 따라서 전체 텍스트 인덱스를 반전된 인덱스라고 부르기도 합니다.
또한 전체 텍스트 인덱스에서 "and" 키워드가 제거되었습니다. 왜냐하면 "and"가 중지 단어이고 전체 텍스트 인덱스에서 중지 단어를 제거하면 디스크 공간이 크게 절약되어 쿼리 성능을 높일 수 있기 때문입니다. 중지 단어에 대한 자세한 내용은 중지 단어 및 중지 목록를 참조하십시오.
조각 1
Keyword |
ColId |
DocId |
Occurrence |
---|---|---|---|
Crank |
1 |
1 |
1 |
Arm |
1 |
1 |
2 |
Tire |
1 |
1 |
4 |
Maintenance |
1 |
1 |
5 |
Front |
1 |
2 |
1 |
Front |
1 |
3 |
1 |
Reflector |
1 |
2 |
2 |
Reflector |
1 |
2 |
5 |
Reflector |
1 |
3 |
2 |
Bracket |
1 |
2 |
3 |
Bracket |
1 |
3 |
3 |
Assembly |
1 |
2 |
6 |
3 |
1 |
2 |
7 |
Installation |
1 |
3 |
4 |
Keyword 열에는 인덱싱할 때 추출한 단일 토큰이 표시됩니다. 토큰을 구성하는 요소는 단어 분리기에 의해 결정됩니다.
ColId 열에는 전체 텍스트 인덱싱된 특정 열에 해당하는 값이 포함됩니다.
DocId 열에는 전체 텍스트 인덱싱된 테이블의 특정 전체 텍스트 키 값으로 매핑되는 8바이트 정수 값이 포함됩니다. 이 매핑은 전체 텍스트 키가 정수 데이터 형식이 아닌 경우에만 필요합니다. 이러한 경우 전체 텍스트 키 값과 DocId 값 사이의 매핑은 DocId Mapping 테이블이라는 개별 테이블에서 유지됩니다. 이러한 매핑을 쿼리하려면 sp_fulltext_keymappings 시스템 저장 프로시저를 사용합니다. 검색 조건을 충족하려면 위 테이블의 DocId 값이 쿼리 중인 기본 테이블에서 행을 검색할 수 있도록 DocId Mapping 테이블과 조인되어야 합니다. 기본 테이블의 전체 텍스트 키 값이 정수 형식인 경우 값은 DocId로 직접 사용되며 매핑이 필요하지 않습니다. 따라서 정수 전체 텍스트 키 값을 사용하면 전체 텍스트 쿼리 최적화에 도움이 될 수 있습니다.
Occurrence 열에는 정수 값이 포함됩니다. 각 DocId 값에는 해당 DocId 내의 특정 키워드에 대한 상대적 단어 오프셋에 해당하는 발생 빈도 값의 목록이 있습니다. 발행 빈도 값은 구 또는 근접 단어 일치를 확인하는 데 유용합니다. 예를 들어 구는 발생 빈도 값의 숫자가 서로 인접해 있습니다. 발생 빈도 값은 관련성을 평가하는 데에도 유용합니다. 예를 들어 DocId의 키워드 발생 빈도를 평가 시 사용할 수 있습니다.
전체 텍스트 인덱스 조각
논리적 전체 텍스트 인덱스는 일반적으로 여러 개의 내부 테이블로 분할됩니다. 이러한 각 내부 테이블을 전체 텍스트 인덱스 조각이라고 부릅니다. 이러한 조각 중 일부는 비교적 최신의 데이터를 포함할 수도 있습니다. 예를 들어 사용자가 DocId가 3인 다음 행을 업데이트하고 테이블에서 자동으로 변경 내용이 추적되는 경우 새로운 조각이 만들어집니다.
DocumentID |
Title |
---|---|
3 |
Rear Reflector |
다음 예제에서 조각 2에 포함된 DocId 3 관련 데이터는 조각 1에 포함된 데이터에 비해 새로운 데이터입니다. 따라서 사용자가 "Rear Reflector"를 쿼리하면 조각 2의 데이터가 DocId 3에 대해 사용됩니다. 각 조각은 생성 타임스탬프로 구분되며 이 타임스탬프는 sys.fulltext_index_fragments 카탈로그 뷰를 사용하여 쿼리할 수 있습니다.
조각 2
Keyword |
ColId |
DocId |
Occ |
---|---|---|---|
Rear |
1 |
3 |
1 |
Reflector |
1 |
3 |
2 |
조각 2에서 볼 수 있듯이 전체 텍스트 쿼리에서는 각 조각을 내부적으로 쿼리하고 이전 항목을 무시해야 합니다. 따라서 전체 텍스트 인덱스에 전체 텍스트 인덱스 조각이 너무 많으면 쿼리 성능이 크게 저하될 수 있습니다. 조각 수를 줄이려면 ALTER FULLTEXT CATALOGTransact-SQL 문의 REORGANIZE 옵션을 사용하여 전체 텍스트 카탈로그를 다시 구성합니다. 이 문은 마스터 병합을 수행하고 이 병합에서는 여러 조각을 하나의 큰 조각으로 병합하고 전체 텍스트 인덱스에서 사용되지 않는 항목을 모두 제거합니다.
다시 구성 작업 후 예제 인덱스에는 다음과 같은 행이 포함됩니다.
Keyword |
ColId |
DocId |
Occ |
---|---|---|---|
Crank |
1 |
1 |
1 |
Arm |
1 |
1 |
2 |
Tire |
1 |
1 |
4 |
Maintenance |
1 |
1 |
5 |
Front |
1 |
2 |
1 |
Rear |
1 |
3 |
1 |
Reflector |
1 |
2 |
2 |
Reflector |
1 |
2 |
5 |
Reflector |
1 |
3 |
2 |
Bracket |
1 |
2 |
3 |
Assembly |
1 |
2 |
6 |
3 |
1 |
2 |
7 |