clob和blob是不是可以进行模糊查询_你知道什么是 MySQL 的模糊查询?

12670802e72c1cbaa55c2e9a78ba8678.gif

2af25f80ca8ab9f6ef90b673faafd689.png

作者 | luanhz

责编 | 郭芮

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

6d5ce71985e0203a04da759918c7061b.png

引言MySQL根据不同的应用场景,支持的模糊搜索方式有多种,例如应用最广泛的可能是Like匹配和RegExp正则匹配,二者虽然用法和原理都很相似,但实际上匹配原则却不尽相同,其中Like要求模式串与整个目标字段完全匹配才检索该记录,而RegExp则是要求目标字段包含模式串即可。对于简单的判断模式串是否存在类型的模糊搜索,应用MySQL内置函数即可实现,例如Instr()、Locate()、Position()等。当然,提到MySQL查询性能就不得不提到索引,对于字段模糊查询需求,我们也可以考虑添加全文索引(Fulltext)。注:本文所用MySQL版本8.0.19,可视化工具Navicat Primium。

c4bb53582500f3faade73bdac1d5f5ee.png

4种模糊查询为了便于描述和测试不同模糊查询方式结果,首先给出一个简单的测试用数据表tests如下:f1905df0be8e53cda7b8f969e2df486f.png其中,tests表仅含有一个名为words的字段,并对该字段添加全文索引。表中共有6条记录。2b2e6e0bad367da07a25970c1c832231.pngLikeLike算作MySQL中的谓词,其应用与is、=、>和例如,在如上表中查找所有以"hello"开头的记录,则其SQL语句为:
1SELECT words FROM tests WHERE words LIKE 'hello%';
查询结果:4acc69ee2affe4535b5b6840e11ea7fc.png如果想查找所有以"hello"开头且至少含有6个字符的记录,则可简单修改SQL语句如下:
1SELECT words FROM tests WHERE words LIKE 'hello_%';
查询结果:9bc3b0a88559f34715e90652b8c0e494.png另外:当在Like模式字段中,若不包含任何"_"和"%"通配符,则等价于"=",表示精确匹配,例如查询语句……Like "hello",则仅返回hello一条记录;还可在Like前加限定词Not,表示结果取反。RegExp正则表达式具有庞大而丰富的语法,MySQL语法中支持绝大部分正则表达式功能,几乎可以满足所有需求。本文不过多展开正则表达式相关介绍,仅在Like的基础上,简单介绍其与Like模糊搜索方式的区别。如前所述,Like匹配原则是要求模式串与整个目标字段匹配时,才返回该条记录;而RegExp中则是当目标字段包含模式串时即返回该条记录。例如如下SQL语句将返回所有包含"hello"的记录:
1SELECT words FROM tests WHERE words REGEXP 'hello';
而在Like中这样的写法仅返回记录="hello"的记录。为了限定正则表达式以某个模式串开头或者结尾,可以通过添加"^"和"$"标识符来限定,例如仍然搜索以"hello"开头的目标字段,则其SQL语句为:
1SELECT words FROM tests WHERE words REGEXP '^hello';
内置函数对于包含某些特定模式串的模糊搜索,可以通过MySQL内置函数实现。可以完成这一功能的函数包括Instr()、Locate()和Position()等,其功能语法很相近,均是返回子串在字符串中的索引,且索引下标从1开始,当子串不存在是返回0。需要注意的是三个函数中子串和字符串的先后顺序是不一致的。例如以下语句均成功检索,且返回目标索引1
1SELECT INSTR("hello,world", 'hello');-- 12SELECT LOCATE('hello', "hello,world");-- 13SELECT POSITION('hello' in "hello, world"); -- 1
应用以上3个内置函数,搜索上述测试表中包含"hello"的记录,则相应SQL语句为:
1SELECT words  FROM tests WHERE INSTR(words, 'hello');2SELECT words  FROM tests WHERE LOCATE('hello', words);3SELECT words  FROM tests WHERE POSITION('hello' in words);
全文索引抛开索引谈查询性能,都是耍流氓!全文索引是MySQL中索引的一种,曾经仅在引擎为MyISAM的表中支持,从5.6版本开始在InnoDB中也开始支持全文索引,支持的字段格式包括CHAR、VARCHAR和TEXT。在如上已经添加了全文索引的tests表中,仍然查询包含"hello"的记录,应用全文索引查询的SQL语句为:
1SELECT words FROM tests WHERE MATCH(words) against('hello');
实际上,MATCH(words) against('hello')返回的是字段words对目标字符"hello"的匹配程度:当不存在任何匹配结果时,返回0;否则,根据匹配次数的多少和位置先后返回一个匹配度。例如,如下SQL语句返回表中每条记录对目标字段"hello"的匹配度:
1SELECT MATCH(words) against('hello') FROM tests;
返回结果如下:46d7843bd244fd93d8ab186b97f4e2f3.png

ec6b0f32bb81d924768abef2f88cea11.png

查询性能对比为了对比以上4种模糊搜索方式的性能,我们这里构建一个规模较大且更具一般性的数据表。本文选择采集若干条英文格言,用于创建目标数据库。创建数据表为简单起见,仅创建一个名为says的字段,且对其添加全文索引。
1CREATE TABLE IF NOT EXISTS sayings(says TEXT, FULLTEXT (says));
英文格言信息获取在网上找了个英文格言的网站,并写了一个python小爬虫爬取页面全部300条英文格言,爬虫源码如下(为了增加记录条数,将300条记录重写100词,即数据库中包含30000条记录):
 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)
对爬取的英文短句写入创建的数据表中,结果如下:ae2edf4ba1d9546b6120e5054554f1f8.png既然是英文励志格言短句,那么我们就来查询其中包括"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通配符速度其次,但与其他几种查询方式效率相差不大。通过Explain查询计划,我们可以发现全文索引方式由于应用了索引而无需全表查询,所以执行速度快,而其他三种模糊查询方式均为执行全表查询。bce3dfaa60be0b679f6c919db6bcb394.png全文索引查询计划2593f7ee8c71cf767f9f3ef52fe61a1f.pngLike通配符查询计划实际上,对于添加索引的字段应用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查询效率提升明显,并大幅超过其他方式。但解释查询计划发现,虽然possible_key显示了索引字段,但实际仍然未应用任何索引(key为null),即仍然进行全表查询(Type = All)。之所以带来速度上的大幅提升,仅仅是因为对'success%'要比'%success%'执行字符串匹配要快得多(后者要整列匹配,前者仅需匹配开头的单词即可),而与索引无关。f7343488651be615b4a1d21ed7611845.pngLike'success%'仍然无法应用全文索引所以,得到的结论是Like通配符无法有效利用全文索引加速查询,但在特定模式下的查询速度可快于通配符%模式下的查询。

51d43953a26f6445f1fee792a85be33f.png

总结本文探讨了MySQL中4中模糊查询方式,包括:
  • Like通配符用于查询目标字段与模式串完全匹配的记录,且无法应用全文索引提高查询速度,但以特定字符开头的模糊查询比以"%"开头时速度提升明显;

  • RegExp正则表达式功能强大,可实现任意模式查询,但执行效率一般;

  • 简单的子串有无查询还可应用MySQL内置函数,包括Instr()、Locate()和Position()等,用法相近,但效率一般;

  • 对于包含全文索引的目标字段查询,应用全文索引查询效率最高,但可定制性差,不支持任意匹配查询;

  • 记录数目较少时,几种查询方式效率均可接受,可根据任务需求灵活选用。

声明:本文为作者投稿,版权归其所有。

【END】

5d45821c7885f6faaf6ede67ba458cb7.png

8b7798157a7b3a3faede5f52feeceea9.png

今日福利

遇见大咖

由 CSDN 全新专为技术人打造的高端对话栏目《大咖来了》来啦!

CSDN 创始人&董事长、极客帮创投创始合伙人蒋涛携手京东集团技术副总裁、IEEE Fellow、京东人工智能研究院常务副院长、深度学习及语音和语言实验室负责人何晓冬,来也科技 CTO 胡一川,共话中国 AI 应用元年来了,开发者及企业的路径及发展方向!

,直达报名:https://t.csdnimg.cn/uZfQ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/473032.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个长文档里,包括封面、不同的章节,如果我想封面不设置页眉页脚,每个章节的页眉都不同,请问应该如何设置页眉页脚?

问:在一个长文档里,包括封面、不同的章节,如果我想封面不设置页眉页脚,每个章节的页眉都不同,请问应该如何设置页眉页脚? 答:如果只需要首页不同,可选择“文件”菜单下的“页面设置”…

LintCode 1917. 切割剩余金属

文章目录1. 题目2. 解题1. 题目 描述 金属棒工厂的厂长拥有 n 根多余的金属棒。 当地的一个承包商提出,只要所有的棒材具有相同的长度(用 saleLength 表示棒材的长度),就将金属棒工厂的剩余棒材全部购买。 厂长可以通过将每根棒…

太原理工电子信焦工程_电气工程及其自动化专业毕业后做什么工作?近几年就业和收入怎样...

本文内容为各大高校往届大学生真实的现身说法内容,但因为是往届,每年该专业的大学情况可能会发生略微变化,所以部分内容较今年,明年甚至以后几年,实际情况可能会略有不同但是对于本专业的相关信息还是非常有参考价值的…

js定时器和linux命令locate

js定时器如果带有参数,应该采用如下方式 setTimeout(function(){function(param)},1000); 匿名函数的方法。 linux locate基于数据库的查找方法。转载于:https://www.cnblogs.com/birdskyws/p/3974556.html

编程竞赛控制系统(PC2)使用说明书

编程竞赛控制系统(PC2)使用说明书 1. 系统简介 PC2是由美国加利福尼亚大学为国际大学生编程竞赛开发研制的竞赛控制系统。目前主要用于ACM/ICPC等国际编程竞赛。PC2最新的版本是8.5d,系统采用JAVA语言编写,可以运行在任何支持JAVA的平台(windows…

怎么查看linux日志里请求量最高的url访问最多的_实用的Linux高级命令,开发运维都要懂!...

在运维的坑里摸爬滚打好几年了,我还记得我刚开始的时候,我只会使用一些简单的命令,写脚本的时候,也是要多简单有多简单,所以有时候写出来的脚本又长又臭。像一些高级点的命令,比如说 Xargs 命令、管道命令、…

ggplot2箱式图两两比较_第十九章_使用ggplot2进行高级绘图

介绍ggplot2包使用形状、颜色和尺寸来对多元数据进行可视化用刻面图比较各组自定义ggplot2图19.1 R中的四种图形系统基础gridlatticeggplot2(用的较多)gghub需要的R包ggpolt2gridExtra(可以拼图)car19.2 ggplot2介绍library(ggplot2)ggplot(datamtcars, aes(xwt, ympg)) geom_p…

centos7 編譯 chmsee

安装libchm及相关的devel包,安装 xulrunner 及 devel 包!否则后面make的时候会出错! 到解压出来的chmsee/src目录下,找到与你系统对应的Makefile文件,我选的是Makefile.fedora,cp Makefile.fedora Makefile…

python调用cmd命令释放端口_详解python调用cmd命令三种方法

目前我使用到的python中执行cmd的方式有三种 使用os.system("cmd") 该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码,高位为脚本的退出状态码,即脚本中“exit 1”的代码执行后,os.system函数返回值的高位数则是1,如果低位数是0的情…

LeetCode 1742. 盒子中小球的最大数量

文章目录1. 题目2. 解题1. 题目 你在一家生产小球的玩具厂工作,有 n 个小球,编号从 lowLimit 开始,到 highLimit 结束(包括 lowLimit 和 highLimit ,即 n highLimit - lowLimit 1)。 另有无限数量的盒子…

bash shell命令(1)

本文地址:http://www.cnblogs.com/archimedes/p/bash-shell1.html,转载请注明源地址。 ls命令 ls用来列出目录的内容,它是用户最常用的命令之一,ls命令的格式为: ls[选项][目录名或文件名] 选项的主要参数:…

activiti页面展示流程图乱码_activiti 5.17 流程图中文乱码问题

1. 流程图中任务中的中文乱码显示问题。解决方法:设置processEngineConfiguration中的两个字体属性,例如:。。。2. 流程图中TextAnnotation中的中文乱码显示问题。此乱码产生的原因是,负责画流程图的类DefaultProcessDiagramCanva…

python遍历文件夹下所有文件名中含有指定_Python 遍历目录找出包含指定字符串的文件夹...

题目:编写一个程序,能在当前目录以及当前目录的所有子目录下查找文件名包含指定字符串的文件,并打印出相对路径 题目不难,但是初接触Python,对函数不够熟悉,犯了不少错误。总结如下: os.path.is…

LeetCode 1743. 从相邻元素对还原数组(拓扑排序)

文章目录1. 题目2. 解题1. 题目 存在一个由 n 个不同元素组成的整数数组 nums ,但你已经记不清具体内容。 好在你还记得 nums 中的每一对相邻元素。 给你一个二维整数数组 adjacentPairs ,大小为 n - 1 ,其中每个 adjacentPairs[i] [ui, v…

BP神经网络算法学习

BP(Back Propagation)网络是1986年由Rumelhart和McCelland为首的科学家小组提出,是一种按误差逆传播算法训练的多层前馈网络,是眼下应用最广泛的神经网络模型之中的一个。BP网络能学习和存贮大量的输入-输出模式映射关系&#xff…

phppage类封装分页功能_PHP封装的page分页类定义与用法完整示例

本文实例讲述了PHP封装的page分页类定义与用法。分享给大家供大家参考,具体如下:亲测有效,见下图>1. 测试实例test.phpheader("Content-Type: text/html; charsetutf-8");date_default_timezone_set("Asia/Shanghai")…

ms agent

Microsoft Agent是微软公司于1997年9月发布的一项代理软件开发技术,而后被集成到Internet Explorer 4.0 Plus及更高版本中,目前版本为2.0,支持简体中文。作为一种软件代理工具,Agent以其强大的交互功能、鲜明的人性特点、优美的操…

无向图的深度优先遍历非递归_【数据结构图(一)】什么是图

一、什么是“图”(Graph) 表示“多对多”的关系包含一组顶点:通常用 V (Vertex) 表示顶点集合一组边:通常用 E (Edge) 表示边的集合无向边:(v, w) 有向边:不考虑重边和自回路二、抽象数据类型定义类型名称:图(Graph)数…

LeetCode 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?(前缀和)

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的正整数数组 candiesCount ,其中 candiesCount[i] 表示你拥有的第 i 类糖果的数目。 同时给你一个二维数组 queries ,其中 queries[i] [favoriteTypei, favoriteDayi, dailyCapi] 。 你按照如下…

wdcp-apache开启KeepAlive提高响应速度

因为我们的网站,媒体文件,js文件,css文件等都在同一个服务器上,并且,我们网站有非常多的图片,所以当建立好tcp链接之后,不应该马上关闭连接,因为每建立一次连接还要进行dns解析&…