相信大家一定对在一个大表中使用LIKE ‘%%’作为主要筛选条件进行查询的人深恶痛绝,完全没有办法用索引,简直就是效率杀手。更严重的是,它会占住数据库的CPU资源,导致其他业务无法进行。然而更可悲的是,有时我们在业务中又无法避免这样的使用,比如查询评论中的敏感词。
好消息是,MySQL5.6可以在Innodb上使用全文索引,并在5.7.6以后开始支持中文全文搜索,因此,你要做的只是在需要全文索引的列上加上索引:
ALTER TABLE table ADD FULLTEXT INDEX fulltxt_col1_col2 (col1, col2);
当然,并不是说这样你就可以放心大胆的使用LIKE ‘%%’了,全文搜索需要特殊的语法支持,下面的内容就是对这种语法的介绍,更准确全面的介绍请参考MySQL官方文档
这种语法简单的说就是MATCH…AGAINST:
MATCH (col1,col2,...) AGAINST (expr [search_modifier])
这其中包含了四种搜索修饰符,让你可以根据不同的情况选择使用:
search_modifier:
{
IN NATURAL LANGUAGE MODE
| IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
| IN BOOLEAN MODE
| WITH QUERY EXPANSION
}
MySQL的全文搜索分为三种:natural language search, boolean search, query expansion search, 下面我们来一一介绍:
SELECT COUNT(*) FROM articles
WHERE MATCH (title,body)
AGAINST ('database' IN NATURAL LANGUAGE MODE);
SELECT id, MATCH (title,body)
AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) AS score
FROM articles;
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);
boolean search可以通过一些符号来增加或减少某些词在搜索中所占的权重
-- 匹配既有管理又有数据库的记录
SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('+数据库 +管理' IN BOOLEAN MODE);
-- 匹配有数据库,但是没有管理的记录
SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('+数据库 -管理' IN BOOLEAN MODE);
For example, a user searching for “database” may really mean that “MySQL”, “Oracle”, “DB2”, and “RDBMS” all are phrases that should match “databases”
扩展模式类似于联想,当你输入database进行搜索时,MySQL/Oracle/DB2等词语也会被认为是匹配的