全文索引不同于常見的聚集索引或非聚集索引,這些索引的内部實作是平衡樹(B-Tree)結構,而全文索引在實體上是由一系列的内部表(Internal tables)構成的,這些内部表稱作全文索引片段(Fragment),每一個索引片段也叫做一個倒轉索引(Inverted index),也就是說,每一個倒轉索引都是由一個内部表(Internal Table)實作的。
有一些好奇的朋友可能會發問:“為什麼一個全文索引是由一系列的倒轉索引構成的,而不是一個?為什麼叫做倒轉索引,把什麼倒轉了?”
當建立全文索引之後,全文索引隻有一個索引片段(Fragment),索引片段中沒有備援的資料,從全文索引中執行contains指令時,隻需要從這一個倒轉索引中查找,傳回結果即可。随着業務資料的更新,基礎表(underlying table)的資料也會更新,這時,全文索引會建立新的倒轉索引,但是,舊的資料沒有被删除,這樣會導緻倒轉索引的數量增加,也就是說,全文索引的片段增加,此時,全文索引就是由一系列的索引片段構成的。當全文索引的片段持續增多時,從全文索引中進行文本搜尋需要查找更多的資料行,導緻全文搜尋的性能下降。在管理全文索引時,必須對索引片段進行重組(reorganize)或重建(rebuild),把已删除的資料從索引片段中實體删除,減少全文索引的片段數量,提高全文搜尋的性能。
至于為什麼稱作倒轉索引,這跟倒轉索引存儲的資料有關。
一,倒轉索引的結構
為了便于描述,把全文索引中存儲的一行資料叫做一個文檔,每一個文檔都使用唯一的文檔ID(DocID)辨別,這個DocID也就是在建立全文索引之前,必須建立的唯一索引鍵。
大家知道,全文索引中存儲的不是整個文本,而是把文本分詞之後,存儲單個标記(Token)的資訊,标記(Token)是分詞,及其位置等資訊的統稱。在填充全文索引的時候,分詞器(word breader)将字元串拆分成多個單詞。如果單詞是一個停用詞(stopword),那麼該分詞被過濾掉,不會存儲到倒轉索引中,但是停用詞的位置(position)會被考慮,一個分詞在全文索引中的位置(Position)是該分詞在源文本中的位置。簡而言之,倒轉索引中存儲的資料是分詞和DocID之間的映射。
由DocID來查詢分詞,是正向的;而由分詞來定位DocID,是倒轉的,這就是倒轉索引名稱的由來。
例如,一個基礎表Document有兩列,DocumentID和Title,在字段Title上建立全文索引:

全文引擎首先要對Title字段的文本進行分詞,倒轉索引中主要包含四個字段:
Keyword字段:單個分詞,從Title字段中抽取的一個标記(Token)。
ColId字段:列序号,用于标記全文索引的列。
DocId字段:文檔ID,是8Byte的long類型,用于唯一标記目前的文檔。如果唯一索引鍵是整數類型,那麼DocID就是唯一索引鍵;如果唯一索引鍵不是整數類型,那麼DocID經過中間的映射表、唯一映射到唯一索引鍵。是以,整數類型的唯一索引鍵能夠優化全文查詢的性能。
Occurrence字段:分詞的位置,或者叫做偏移量(Offset)。
CreateTime字段:時間戳字段(timestamp ),用于記錄倒轉索引建立的時間。
例如,下圖是Document表的索引片段Fragment1:
對于DocumentID=1的文檔,分詞器把Title字段拆分成5個分詞,這5個分詞分别是:Crank、Arm、and、Tire、Maintenance,出現的位置分别是1,2,3,4,5,由于分詞and是一個停用詞,過濾器會把分詞and過濾掉,但是and分詞的位置會計算在後續的分詞上。是以,分詞Tire的位置(Occurrence)是4,而不是3。
二,全文索引的拆分
全文索引通常會拆分成多個索引片段,一些索引片段可能包含新的資料,而一些索引片段可能包含已經被删除的資料。例如,如果有一個使用者把DocumentID=3的文檔的Title字段更新為Rear Reflector:
全文索引會建立一個索引片段Fragmeng2,如下圖所示,
三,全文索引片段的重組
SQL Server使用master merge來重組全文索引,也就是說,把全文索引的各個索引片段歸并到一個打的片段中,然後把廢棄的文檔從全文索引中删除,這樣重組之後,全文索引中包含的都是純淨的資料:
在填充全文索引時,為了提高全文索引的填充速度,全文引擎使用Range來管理。Range是并行處理的程序,需要大量消耗CPU資源。batch是基礎表(underlying table)的資料塊,每個Range 都會産生多個batch,分batch處理資料能夠提高全文索引填充(population)的速度。SQL Server 從基礎表中讀取資料産生batch,每個batch經過全文引擎的處理,會産生一個索引片段。在填充操作完成後,SQL Server 會進行一次Master Merge 操作,将索引片段歸并到Master Fragment。
全文索引的重組,可以設定排程程式(Schedule),通過Population Schedule tab,建立schedule和Job,按照schedule對全文索引進行重組(reorganize):
四,配置全文索引的停用詞
為了阻止全文索引把停用詞填充到全文索引中,SQL Server允許使用者自定義停用詞清單,把常用詞(這些詞對查詢沒有任何幫助)添加到停用詞清單中。在填充全文索引時,全文引擎會把停用詞過濾掉,這意味着,全文查詢不會搜尋停用詞,盡管全文索引會忽略停用詞,但是,停用詞的位置會被考慮進去,每個分詞的位置是該分詞在源文本中的偏移量。
五,檢視分詞
1,檢視語句的分詞
2,檢視contains 謂詞如何解析 FORMSOF 子句
檢視同源詞, 'query_string' 的格式是: 'FORMSOF( INFLECTIONAL, query_term )'
檢視同義詞, 'query_string' 的格式是: 'FORMSOF( THESAURUS, query_term )'
六,檢視全文索引的中繼資料
1,檢視資料庫中的全文索引
View Code
2,檢視全文索引的所有分詞
3,檢視當個文檔的分詞
4,檢視全文索引的内部表(Internal Tables)
5,檢視每一個倒轉索引的大小和包含的資料行數
字段 Status 表示索引片段的狀态:
0 = Newly created and not yet used
1 = Being used for insert during fulltext index population or merge
4 = Closed. Ready for query
6 = Being used for merge input and ready for query
8 = Marked for deletion. Will not be used for query and merge source.
當狀态值為4或6時,表示索引片段已經是全文索引的一部分,可以被查詢,字段Timestamp表示該索引片段建立的時間戳,時間較晚的索引碎片中存儲的是最新的資料,而時間較早的索引片段中存儲的是被删除/淘汰的資料。在執行全文查詢時,傳回的結果中會丢棄被淘汰的資料。
6,檢視全文索引填充的狀态
參考文檔:
<a href="https://msdn.microsoft.com/en-us/library/cc879306(v=sql.110).aspx" target="_blank">Create and Manage Full-Text Indexes</a>
<a href="https://msdn.microsoft.com/en-us/library/hh213007(v=sql.110).aspx" target="_blank">Manage Full-Text Indexes</a>
<a href="https://msdn.microsoft.com/en-us/library/ms142560(v=sql.110).aspx" target="_blank">Improve the Performance of Full-Text Indexes</a>
<a href="https://msdn.microsoft.com/en-us/library/cc280463(v=sql.110).aspx" target="_blank">sys.dm_fts_parser (Transact-SQL)</a>
本文版權歸作者和部落格園所有,歡迎轉載,但未經作者同意,必須保留此段聲明,且在文章頁面醒目位置顯示原文連接配接,否則保留追究法律責任的權利。
本文轉自悅光陰部落格園部落格,原文連結:http://www.cnblogs.com/ljhdo/p/5540239.html,如需轉載請自行聯系原作者