

作者 | luanhz
责编 | 郭芮
本文对MySQL中几种常用的模糊搜索方式进行了介绍,包括LIKE通配符、RegExp正则匹配、内置字符串函数以及全文索引,最后给出了性能对比。

 其中,tests表仅含有一个名为words的字段,并对该字段添加全文索引。表中共有6条记录。
其中,tests表仅含有一个名为words的字段,并对该字段添加全文索引。表中共有6条记录。 LikeLike算作MySQL中的谓词,其应用与is、=、>和例如,在如上表中查找所有以"hello"开头的记录,则其SQL语句为:
LikeLike算作MySQL中的谓词,其应用与is、=、>和例如,在如上表中查找所有以"hello"开头的记录,则其SQL语句为:1SELECT words FROM tests WHERE words LIKE 'hello%'; 如果想查找所有以"hello"开头且至少含有6个字符的记录,则可简单修改SQL语句如下:
如果想查找所有以"hello"开头且至少含有6个字符的记录,则可简单修改SQL语句如下:1SELECT words FROM tests WHERE words LIKE 'hello_%'; 另外:当在Like模式字段中,若不包含任何"_"和"%"通配符,则等价于"=",表示精确匹配,例如查询语句……Like "hello",则仅返回hello一条记录;还可在Like前加限定词Not,表示结果取反。RegExp正则表达式具有庞大而丰富的语法,MySQL语法中支持绝大部分正则表达式功能,几乎可以满足所有需求。本文不过多展开正则表达式相关介绍,仅在Like的基础上,简单介绍其与Like模糊搜索方式的区别。如前所述,Like匹配原则是要求模式串与整个目标字段匹配时,才返回该条记录;而RegExp中则是当目标字段包含模式串时即返回该条记录。例如如下SQL语句将返回所有包含"hello"的记录:
另外:当在Like模式字段中,若不包含任何"_"和"%"通配符,则等价于"=",表示精确匹配,例如查询语句……Like "hello",则仅返回hello一条记录;还可在Like前加限定词Not,表示结果取反。RegExp正则表达式具有庞大而丰富的语法,MySQL语法中支持绝大部分正则表达式功能,几乎可以满足所有需求。本文不过多展开正则表达式相关介绍,仅在Like的基础上,简单介绍其与Like模糊搜索方式的区别。如前所述,Like匹配原则是要求模式串与整个目标字段匹配时,才返回该条记录;而RegExp中则是当目标字段包含模式串时即返回该条记录。例如如下SQL语句将返回所有包含"hello"的记录:1SELECT words FROM tests WHERE words REGEXP 'hello';1SELECT words FROM tests WHERE words REGEXP '^hello';1SELECT INSTR("hello,world", 'hello');-- 12SELECT LOCATE('hello', "hello,world");-- 13SELECT POSITION('hello' in "hello, world"); -- 11SELECT words  FROM tests WHERE INSTR(words, 'hello');2SELECT words  FROM tests WHERE LOCATE('hello', words);3SELECT words  FROM tests WHERE POSITION('hello' in words);1SELECT words FROM tests WHERE MATCH(words) against('hello');1SELECT MATCH(words) against('hello') FROM tests;

1CREATE TABLE IF NOT EXISTS sayings(says TEXT, FULLTEXT (says)); 1from pyquery import PyQuery  as pq 2from pymysql import connect 3 4doc = pq(url='http://www.1juzi.com/new/43141.html', encoding = 'gb18030') 5items=doc("div.content>p:nth-child(2n+1)").items() 6hots = [item.text() for item in items] 7with connect(host="localhost", user="root", password="123456", db='teststr', charset='utf8') as cur: 8    sql_insert = 'insert into sayings values (%s);' 9    for _ in range(100):10        cur.executemany(sql_insert, hots) 既然是英文励志格言短句,那么我们就来查询其中包括"success"的记录。首先查询语句中任意位置包含"success"的记录,4种方式SQL语句及执行时间为:
既然是英文励志格言短句,那么我们就来查询其中包括"success"的记录。首先查询语句中任意位置包含"success"的记录,4种方式SQL语句及执行时间为: 1-- LIKE通配符 2SELECT says FROM sayings WHERE says LIKE '%success%' 3> OK 4> 时间: 0.036s 5 6-- REGEXP正则匹配 7SELECT says FROM sayings WHERE says REGEXP 'success' 8> OK 9> 时间: 0.053s1011-- 内置函数查找12SELECT says FROM sayings WHERE INSTR(says, 'success')13> OK14> 时间: 0.045s1516SELECT says FROM sayings WHERE LOCATE('success', says)17> OK18> 时间: 0.044s1920SELECT says FROM sayings WHERE POSITION('success' in says)21> OK22> 时间: 0.047s2324-- 全文索引25SELECT says FROM sayings WHERE MATCH(says) against('Success')26> OK27> 时间: 0.006s 全文索引查询计划
全文索引查询计划 Like通配符查询计划实际上,对于添加索引的字段应用Like查询时,可以应用索引加速查询,为勒验证全文索引条件下是否仍然可以应用索引,我们进行第二组性能测试:查询语句中以"success"开头的记录(全文索引方式不支持指定单词开头的查询任务),相应SQL语句即执行时间如下:
Like通配符查询计划实际上,对于添加索引的字段应用Like查询时,可以应用索引加速查询,为勒验证全文索引条件下是否仍然可以应用索引,我们进行第二组性能测试:查询语句中以"success"开头的记录(全文索引方式不支持指定单词开头的查询任务),相应SQL语句即执行时间如下: 1SELECT says FROM sayings WHERE says LIKE 'success%' 2> OK 3> 时间: 0.015s 4 5SELECT says FROM sayings WHERE says REGEXP '^success' 6> OK 7> 时间: 0.046s 8 9SELECT says FROM sayings WHERE INSTR(says, 'success')=110> OK11> 时间: 0.042s1213SELECT says FROM sayings WHERE LOCATE('success', says)=114> OK15> 时间: 0.051s1617SELECT says FROM sayings WHERE POSITION('success' in says)=118> OK19> 时间: 0.049s2021SELECT says FROM sayings WHERE MATCH(says) against('Success')22> OK23> 时间: 0.007s Like'success%'仍然无法应用全文索引所以,得到的结论是Like通配符无法有效利用全文索引加速查询,但在特定模式下的查询速度可快于通配符%模式下的查询。
Like'success%'仍然无法应用全文索引所以,得到的结论是Like通配符无法有效利用全文索引加速查询,但在特定模式下的查询速度可快于通配符%模式下的查询。
- Like通配符用于查询目标字段与模式串完全匹配的记录,且无法应用全文索引提高查询速度,但以特定字符开头的模糊查询比以"%"开头时速度提升明显; 
- RegExp正则表达式功能强大,可实现任意模式查询,但执行效率一般; 
- 简单的子串有无查询还可应用MySQL内置函数,包括Instr()、Locate()和Position()等,用法相近,但效率一般; 
- 对于包含全文索引的目标字段查询,应用全文索引查询效率最高,但可定制性差,不支持任意匹配查询; 
- 记录数目较少时,几种查询方式效率均可接受,可根据任务需求灵活选用。 
声明:本文为作者投稿,版权归其所有。
【END】

今日福利
遇见大咖
由 CSDN 全新专为技术人打造的高端对话栏目《大咖来了》来啦!
CSDN 创始人&董事长、极客帮创投创始合伙人蒋涛携手京东集团技术副总裁、IEEE Fellow、京东人工智能研究院常务副院长、深度学习及语音和语言实验室负责人何晓冬,来也科技 CTO 胡一川,共话中国 AI 应用元年来了,开发者及企业的路径及发展方向!
,直达报名:https://t.csdnimg.cn/uZfQ