全文索引,創建全文索引?( 二 )


全文索引緩存只緩存最近插入的行,查詢時,已經刷入磁盤(附屬索引表)的數據不會再回到索引緩存中 。附屬索引表中的內容是直接查詢的,最終返回的結果返回前需要將附屬索引表的結果和索引緩存中的結果合并 。
InnoDB使用被稱作DOC_ID的唯一文件描述符,將全文索引中的單詞與該單詞在文檔中的記錄映射起來 。映射關系需要索引表中的 FTS_DOC_ID 列 。在創建全文索引時,如果沒有定義 FTS_DOC_ID 列,InnoDB會自動的加入一個隱藏的 FTS_DOC_ID 列 。下面是一個例子,
CREATE FULLTEXT INDEX ft_index ON xxxxxxxx(CONTEXT)
[2021-11-12 18:14:04] [HY000][124] InnoDB rebuilding table to add column FTS_DOC_ID
重點看一下這一行: [HY000][124] InnoDB rebuilding table to add column FTS_DOC_ID,InnoDB重新構建了這個表,并且添加了一個列 FTS_DOC_ID。
在CREATE TABLE的過程中添加 FTS_DOC_ID 的時間成本要低于在已經有數據的表上建立全文索引 。如果在表加載數據之前定義 FTS_DOC_ID 列,這個表和它的索引都不需要為了新增列而重新構建 。如果你不需要考慮 CREATE FULLTEXT INDEX 的性能,可以讓InnoDB為你創建 FTS_DOC_ID 列 。InnoDB會新增一個隱藏的 FTS_DOC_ID 列,并且在 FTS_DOC_ID 上建立唯一索引(FTS_DOC_ID_INDEX) 。如果你想自行創建 FTS_DOC_ID 列,這個列必須定義為 BIGINT UNSIGNED NOT NULL 且命名為FTS_DOC_ID(全大寫),如下例子:
如果你自行定義 FTS_DOC_ID 列的話,你需要負責管理這個列,避免空值(empty)或者重復值 。FTS_DOC_ID 的值是不能被重復利用的,所以也就是說 FTS_DOC_ID 的值是需要一直增加的 。
或者,你可以在 FTS_DOC_ID 列上創建所必須的唯一索引FTS_DOC_ID_INDEX(全大寫) 。
mysql CREATE UNIQUE INDEX FTS_DOC_ID_INDEX on opening_lines(FTS_DOC_ID);
如果你沒有創建FTS_DOC_ID_INDEX,InnoDB會自動創建 。
在MySQL 5.7.13前,允許更大FTS_DOC_ID與最新的FTS_DOC_ID之間的間隔為10000,在MySQL 5.7.13及之后的版本中,這個允許的間隔為65535 。
為了避免重新構建表,FTS_DOC_ID列在刪除了全文索引之后依然被保留 。
刪除被索引文件的一個記錄,可能會在附屬索引表中產生非常多的小的刪除項,在并發訪問時,會產生熱點問題 。為了避免這個問題,每當被索引表中的記錄被刪除時,會將被刪文檔的DOC_ID記錄在一個特別的 FTS_*_DELETED 表中,同時全文索引中已經索引了的記錄依然被保存 。在返回查詢結果前,使用 FTS_*_DELETED 中的信息去過濾掉已經刪除掉了的DOC_ID 。這種設計的優勢在于刪除速度快且消耗低 。不好的地方在于索引的大小不能隨著記錄的刪除而立即減少 。為了刪除已刪除記錄在全文索引中的項,需要對被索引的表執行OPTIMIZE TABLE,配合[ innodb_optimize_fulltext_only=ON ],去重構全文索引 。
細節略,有例子:
全文搜索只能看到已經提交了的數據 。
你可以通過查詢下面的INFORMATION_SCHEMA表,來監控或測試InnoDB的一些特殊文本處理 。
默認的分詞器不支持中文,不能檢索到中文中的英文單詞 。
InnoDB默認的Stopwords:
select * from information_schema.INNODB_FT_DEFAULT_STOPWORD;
SQL中的關鍵詞(保留關鍵字):
Shell中的關鍵詞:for,while,echo
其他:###, ***, --,
被索引表數據量、索引表數據量
模糊匹配與嚴格匹配的性能差距
需要將 innodb_optimize_fulltext_only 配置為ON,這里是否需要DBA在MySQL鏡像中修改?
innodb_optimize_fulltext_only 設置為ON后,對系統有何影響需要評估 。
innodb_optimize_fulltext_only
執行的時間、頻率 。
MySQL內建的全文檢索解析器使用單詞之間的空白作為分隔符以標識單詞的頭尾,但是這里有個限制,對于表意文字,它是沒有單詞分隔符的 。為了解決這個限制,MySQL提供了支持中文、日語、韓語的 ngram 解析器 。ngram解析器支持InnoDB和MyISAM 。
Ngram是內建在服務中的插件,像其他自建在服務中的插件一樣,服務啟動時會自動加載它 。全文檢索的語法參考上面(Section 12.10, “Full-Text Search Functions”),這里只討論一些不同的地方 。除了單詞的最小、更大長度配置項([ innodb_ft_min_token_size ]innodb_ft_max_token_size,ft_min_word_len,ft_max_word_len,全文檢索依賴一些配置項都是可以使用的 。
Ngram默認索引的單詞(token)的大小為2( 2bigram ) 。例如,索引的大小為2,Ngram解析器解析字符串“abc def”為四個單詞元素(tokens):“ab”, “bc”, “de” and “ef” 。
ngram token size is configurable using thengram_token_sizeconfiguration option,which has a minimum value of 1 and maximum value of 10.

推薦閱讀