目錄html
咱們在用一個東西前,得知道爲何要用它,使用全文索引無非有如下緣由mysql
簡單的說,全文索引就至關於大詞典中的目錄,經過查詢目錄能夠快速定位到想看的內容。
全文索引經過創建倒排索引
來快速匹配文檔(僅在mysql5.6版本以上支持)
全文索引將連續的字母、數字和下劃線
當作一個單詞,分割單詞通常用空格/逗號/句號
MySQL的全文索引支持如下3種查詢模式:sql
IN NATURAL LANGUAGE MODE
)IN BOOLEAN MODE
)WITH QUERY EXPANSION
)更多請看:官方文檔數據庫
下面教你們如何建立全文索引,並建立測試數據演示三種查詢模式的使用json
CREATE TABLE light_weight_baby ( id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), content TEXT, FULLTEXT(title, content) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
ALTER TABLE table_name ADD FULLTEXT INDEX index_name (column1,column2,...);
CREATE FULLTEXT INDEX index_name ON table_name (column1,column2,...);
建立一個數據庫用來演示這三種模式下的檢索mysql優化
CREATE DATABASE chenqionghe DEFAULT CHARSET utf8;
建立一個文章表並插入測試數據app
CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) ) ENGINE=InnoDB;
插入測試數據dom
INSERT INTO articles (title,body) VALUES ('MySQL Tutorial','DBMS stands for DataBase ...'), ('How To Use MySQL Well','After you went through a ...'), ('Optimizing MySQL','In this tutorial we will show ...'), ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), ('MySQL vs. YourSQL','In the following database comparison ...'), ('MySQL Security','When configured properly, MySQL ...');
執行結果以下
測試
這是MySQL的默認查詢模式,簡單示例以下優化
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE);
能夠看到,不區分大小寫,title或body包含database的都返回了,另外,返回的結果將以相關性進行排序。
相關性:根據行中的字段、惟一單詞的數量、集合中單詞總數和包含特定單詞的行數計算。
下面經過兩種方式統計數量
# 第一種方式 SELECT COUNT(*) FROM articles WHERE MATCH (title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE); # 第二種方式 SELECT COUNT(IF(MATCH (title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL)) AS count FROM articles;
第一種作了一些額外的工做(按相關性對結果進行排序),但也能使用索引進行查詢。
第二種執行了全表掃描,若是搜索項出如今大多數行中,可能比索引查詢更快
匹配少數行,第一種快,匹配大多數行,第二種快
下面演示如何檢索相關性,但不會進行排序(由於不包含WHERE
和ORDER BY
)
SELECT id, MATCH (title,body) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) AS score FROM articles;
下面的示例更復雜,返回倒序後的相關性值,分別在SELECT和WHERE語句中使用了MATCH,可是不會致使額外的開銷,由於mysql優化器注意到兩次MATCH是相同的,只會使用一次全文搜索
SELECT id, body, MATCH (title,body) AGAINST ('Security implications of running MySQL as root' IN NATURAL LANGUAGE MODE) AS score FROM articles WHERE MATCH (title,body) AGAINST ('Security implications of running MySQL as root' IN NATURAL LANGUAGE MODE);
包含在("")中字符中的會被分解爲單詞,而後在全文索引中進行搜索,簡單的說,就是進行OR查詢。
使用布爾模式須要指定IN BOOLEAN MODE
,不會自動根據相關性排序,一些字符具備特殊的含義,例如能夠經過+或-表示一個單詞必須存在或不存在。
下面的sql語句表明查詢必須 包含MySQL但不包含YourSQL
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
+
-
IN BOOLEAN MODE
的結果同樣@distance
MATCH(col1) AGAINST('"word1 word2 word3" @8' IN BOOLEAN MODE
>
<
()
~
+apple ~macintosh
先匹配apple,但若是同時包含macintosh,排名會靠後*
"
apple banana
+apple +juice
+apple macintosh
+apple -macintosh
+apple ~macintosh
+apple +(>turnover <strudel)
apple*
"some words"
當搜索短語很短時很是有用,例如搜索database可能意味着MySQL、Oracle、DB二、RDBMS都要被匹配到,這就是這個模式能作的。
添加WITH QUERY EXPANSION
或 IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
啓用,它會執行兩次檢索,第一次使用給定短語檢索,第二次是結合第一次相關性比較高的行進行檢索。
例以下面的例子
# 天然語言模式 SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE); # 擴展模式 SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database' WITH QUERY EXPANSION);
能夠看到第二條語句找到了包含MySQL的行,即便該行不包含database,可是由於在第一次的搜索中搜索引擎判斷MySQL和database的相關性比較高,因此在執第二次搜索的時候返回了。
innodb_ft_min_token_size
和innodb_ft_max_token_size
用來設置單詞的最大和最小長度,不在這個長度區間的將忽略。