MySQL模糊查询再也不用like+%了

MySQL中如何高效的实现模糊查询(附30条优化建议) 然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。14、并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段 sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。在使用msyql进行模糊查询的时候,很自然的会用到like语句,通常情况下,在数据量小的时候,不容易看出查询的效率,但在数据量达到百万级,千万级的时候,查询的效率就很容易显现出来。 阅读详情

MySQL模糊查询再也不用like+%了

前言

我们都知道 InnoDB 在模糊查询数据时使用 "%xx" 会导致索引失效,但有时需求就是如此,类似这样的需求还有很多,例如,搜索引擎需要根基用户数据的关键字进行全文查找,电子商务网站需要根据用户的查询条件,在可能需要在商品的详细介绍中进行查找,这些都不是B+树索引能很好完成的工作。

通过数值比较,范围过滤等就可以完成绝大多数我们需要的查询了。但是,如果希望通过关键字的匹配来进行查询过滤,那么就需要基于相似度的查询,而不是原来的精确数值比较,全文索引就是为这种场景设计的。

全文索引(Full-Text Search)是将存储于数据库中的整本书或整篇文章中的任意信息查找出来的技术。它可以根据需要获得全文中有关章、节、段、句、词等信息,也可以进行各种统计和分析。

在早期的 MySQL 中,InnoDB 并不支持全文检索技术,从 MySQL 5.6 开始,InnoDB 开始支持全文检索。

倒排索引

全文检索通常使用倒排索引(inverted index)来实现,倒排索引同 B+Tree 一样,也是一种索引结构。它在辅助表中存储了单词与单词自身在一个或多个文档中所在位置之间的映射,这通常利用关联数组实现,拥有两种表现形式:

  • inverted file index:{单词,单词所在文档的id}
  • full inverted index:{单词,(单词所在文档的id,再具体文档中的位置)}

对于 inverted file index 的关联数组

上图为 inverted file index 关联数组,可以看到其中单词"code"存在于文档1,4中,这样存储再进行全文查询就简单了,可以直接根据 Documents 得到包含查询关键字的文档;而 full inverted index 存储的是对,即(DocumentId,Position),因此其存储的倒排索引如下图,如关键字"code"存在于文档1的第6个单词和文档4的第8个单词。相比之下,full inverted index 占用了更多的空间,但是能更好的定位数据,并扩充一些其他搜索特性。

image.png

全文检索

创建全文索引

1、创建表时创建全文索引语法如下:

CREATE TABLE table_name ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, author VARCHAR(200), 
title VARCHAR(200), content TEXT(500), FULLTEXT full_index_name (col_name) ) ENGINE=InnoDB;
复制代码

输入查询语句:

SELECT table_id, name, space from INFORMATION_SCHEMA.INNODB_TABLES
WHERE name LIKE 'test/%';
复制代码

image.png

上述六个索引表构成倒排索引,称为辅助索引表。当传入的文档被标记化时,单个词与位置信息和关联的DOC_ID,根据单词的第一个字符的字符集排序权重,在六个索引表中对单词进行完全排序和分区。

2、在已创建的表上创建全文索引语法如下:

CREATE FULLTEXT INDEX full_index_name ON table_name(col_name);
复制代码

使用全文索引

MySQL 数据库支持全文检索的查询,全文索引只能在 InnoDB 或 MyISAM 的表上使用,并且只能用于创建 char,varchar,text 类型的列。

其语法如下:

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
}
复制代码

全文搜索使用 MATCH() AGAINST()语法进行,其中,MATCH() 采用逗号分隔的列表,命名要搜索的列。AGAINST()接收一个要搜索的字符串,以及一个要执行的搜索类型的可选修饰符。全文检索分为三种类型:自然语言搜索、布尔搜索、查询扩展搜索,下面将对各种查询模式进行介绍。

Natural Language

自然语言搜索将搜索字符串解释为自然人类语言中的短语,MATCH()默认采用 Natural Language 模式,其表示查询带有指定关键字的文档。

接下来结合demo来更好的理解Natural Language

SELECT
    count(*) AS count 
FROM
    `fts_articles` 
WHERE
    MATCH ( title, body ) AGAINST ( 'MySQL' );
复制代码

image.png

上述语句,查询 title,body 列中包含 'MySQL' 关键字的行数量。上述语句还可以这样写:

SELECT
    count(IF(MATCH ( title, body ) 
    against ( 'MySQL' ), 1, NULL )) AS count 
FROM
    `fts_articles`;
复制代码

上述两种语句虽然得到的结果是一样的,但从内部运行来看,第二句SQL的执行速度更快些,因为第一句SQL(基于where索引查询的方式)还需要进行相关性的排序统计,而第二种方式是不需要的。

还可以通过SQL语句查询相关性:

SELECT
    *,
    MATCH ( title, body ) against ( 'MySQL' ) AS Relevance 
FROM
    fts_articles;
复制代码

image.png

相关性的计算依据以下四个条件:

  • word 是否在文档中出现
  • word 在文档中出现的次数
  • word 在索引列中的数量
  • 多少个文档包含该 word

对于 InnoDB 存储引擎的全文检索,还需要考虑以下的因素:

  • 查询的 word 在 stopword 列中,忽略该字符串的查询
  • 查询的 word 的字符长度是否在区间 [innodb_ft_min_token_size,innodb_ft_max_token_size] 内

如果词在 stopword 中,则不对该词进行查询,如对 'for' 这个词进行查询,结果如下所示:

SELECT
    *,
    MATCH ( title, body ) against ( 'for' ) AS Relevance 
FROM
    fts_articles;
复制代码

image.png

可以看到,'for'虽然在文档 2,4中出现,但由于其是 stopword ,故其相关性为0

参数 innodb_ft_min_token_size 和 innodb_ft_max_token_size 控制 InnoDB 引擎查询字符的长度,当长度小于 innodb_ft_min_token_size 或者长度大于 innodb_ft_max_token_size 时,会忽略该词的搜索。在 InnoDB 引擎中,参数 innodb_ft_min_token_size 的默认值是3,innodb_ft_max_token_size的默认值是84

Boolean

布尔搜索使用特殊查询语言的规则来解释搜索字符串,该字符串包含要搜索的词,它还可以包含指定要求的运算符,例如匹配行中必须存在或不存在某个词,或者它的权重应高于或低于通常情况。例如,下面的语句要求查询有字符串"Pease"但没有"hot"的文档,其中+和-分别表示单词必须存在,或者一定不存在。

select * from fts_test where MATCH(content) AGAINST('+Pease -hot' IN BOOLEAN MODE);
复制代码

Boolean 全文检索支持的类型包括:

  • +:表示该 word 必须存在
  • -:表示该 word 必须不存在
  • (no operator)表示该 word 是可选的,但是如果出现,其相关性会更高
  • @distance表示查询的多个单词之间的距离是否在 distance 之内,distance 的单位是字节,这种全文检索的查询也称为 Proximity Search,如 MATCH(context) AGAINST('"Pease hot"@30' IN BOOLEAN MODE)语句表示字符串 Pease 和 hot 之间的距离需在30字节内
  • >:表示出现该单词时增加相关性
  • <:表示出现该单词时降低相关性
  • ~:表示允许出现该单词,但出现时相关性为负
  • * :表示以该单词开头的单词,如 lik*,表示可以是 lik,like,likes
  • " :表示短语

下面是一些demo,看看 Boolean Mode 是如何使用的。

demo1:+ -

SELECT
    * 
FROM
    `fts_articles` 
WHERE
    MATCH ( title, body ) AGAINST ( '+MySQL -YourSQL' IN BOOLEAN MODE );
复制代码

上述语句,查询的是包含 'MySQL' 但不包含 'YourSQL' 的信息

image.png

demo2: no operator

SELECT
    * 
FROM
    `fts_articles` 
WHERE
    MATCH ( title, body ) AGAINST ( 'MySQL IBM' IN BOOLEAN MODE );
复制代码

上述语句,查询的 'MySQL IBM' 没有 '+','-'的标识,代表 word 是可选的,如果出现,其相关性会更高

image.png

demo3:@

SELECT
    * 
FROM
    `fts_articles` 
WHERE
    MATCH ( title, body ) AGAINST ( '"DB2 IBM"@3' IN BOOLEAN MODE );
复制代码

上述语句,代表 "DB2" ,"IBM"两个词之间的距离在3字节之内

image.png

demo4:> <

SELECT
    * 
FROM
    `fts_articles` 
WHERE
    MATCH ( title, body ) AGAINST ( '+MySQL +(>database <DBMS)' IN BOOLEAN MODE );
复制代码

上述语句,查询同时包含 'MySQL','database','DBMS' 的行信息,但不包含'DBMS'的行的相关性高于包含'DBMS'的行。

image.png

demo5: ~

SELECT
    * 
FROM
    `fts_articles` 
WHERE
    MATCH ( title, body ) AGAINST ( 'MySQL ~database' IN BOOLEAN MODE );
复制代码

上述语句,查询包含 'MySQL' 的行,但如果该行同时包含 'database',则降低相关性。

image.png

demo6:*

SELECT
    * 
FROM
    `fts_articles` 
WHERE
    MATCH ( title, body ) AGAINST ( 'My*' IN BOOLEAN MODE );
复制代码

上述语句,查询关键字中包含'My'的行信息。

image.png

demo7:"

SELECT
    * 
FROM
    `fts_articles` 
WHERE
    MATCH ( title, body ) AGAINST ( '"MySQL Security"' IN BOOLEAN MODE );
复制代码

上述语句,查询包含确切短语 'MySQL Security' 的行信息。

image.png

Query Expansion

查询扩展搜索是对自然语言搜索的修改,这种查询通常在查询的关键词太短,用户需要 implied knowledge(隐含知识)时进行,例如,对于单词 database 的查询,用户可能希望查询的不仅仅是包含 database 的文档,可能还指那些包含 MySQL、Oracle、RDBMS 的单词,而这时可以使用 Query Expansion 模式来开启全文检索的 implied knowledge

通过在查询语句中添加 WITH QUERY EXPANSION / IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION 可以开启 blind query expansion(又称为 automatic relevance feedback),该查询分为两个阶段。

  • 第一阶段:根据搜索的单词进行全文索引查询
  • 第二阶段:根据第一阶段产生的分词再进行一次全文检索的查询

接着来看一个例子,看看 Query Expansion 是如何使用的。

-- 创建索引
create FULLTEXT INDEX title_body_index on fts_articles(title,body);
复制代码
-- 使用 Natural Language 模式查询
SELECT
    * 
FROM
    `fts_articles` 
WHERE
    MATCH(title,body) AGAINST('database');
复制代码

使用 Query Expansion 前查询结果如下:

image.png

-- 当使用 Query Expansion 模式查询
SELECT
    * 
FROM
    `fts_articles` 
WHERE
    MATCH(title,body) AGAINST('database' WITH QUERY expansion);
复制代码

使用 Query Expansion 后查询结果如下:

image.png

由于 Query Expansion 的全文检索可能带来许多非相关性的查询,因此在使用时,用户可能需要非常谨慎。

删除全文索引

1、直接删除全文索引语法如下:

DROP INDEX full_idx_name ON db_name.table_name;
复制代码

2、使用 alter table 删除全文索引语法如下:

ALTER TABLE db_name.table_name DROP INDEX full_idx_name;
复制代码

小结

本文从理论与实践结合的角度对 fulltext index 做了介绍,如对 MySQL 感兴趣可继续关注 MySQL 专栏。

解决MySQL数据库中文模糊检索问题 通过利用MySQL的全文搜索功能以及中文分词库,我们可以解决MySQL数据库中文模糊检索问题。通过创建全文索引、配置中文分词库,并使用MATCH AGAINST语句,我们能够获取与输入关键词相似的中文记录。在MySQL数据库中进行中文模糊检索是一个常见的需求,但是由于中文的特殊性,传统的模糊检索方式可能无法得到准确的结果。在MySQL数据库中,我们希望能够进行中文的模糊检索,即通过输入的关键词,在数据库中查找与之相似的中文记录。首先,下载并安装中文分词库。字段的名称,并根据选择的中文分词库进行相应的配置。 阅读详情

相关推荐

MySQL 模糊查询再也不用 like+% 了 —— 深度解析

通过简单的几行 SQL 代码,我们就实现了使用全文索引和正则表达式进行高效的模糊查询。如果你对这个话题还有更多好奇的地方,或者在实践中遇到了问题,记得随时提问哦!此外,如果需要更复杂的全文搜索功能,可以考虑使用专业的搜索引擎如 Elasticsearch。首先,我们需要准备一个 MySQL 数据库,并创建一个包含全文索引的表。接下来,我们将在这个表中插入一些数据,并演示如何使用全文索引进行高效的模糊查询。亲爱的读者们,你们在使用 MySQL 进行模糊查询时遇到过哪些有趣的问题?在大量数据的情况下,使用。

java专栏 1093

MySql模糊查询大全

MySql模糊查找

qq_46940224的博客 7万+

5大绝招!MySQL 模糊查询再也不用 like+% 了

通过以上五个步骤,我们已经成功地优化了MySQL中的模糊查询,让你的应用程序查询速度快如闪电,用户体验直线上升。希望这篇文章对你有所帮助,让你的开发之路更加轻松愉快!如果你有任何问题或建议,欢迎随时留言交流。祝你在编程的世界里越走越远,越飞越高!🚀🎉希望这篇文章能帮助你更好地理解和应用MySQL中的模糊查询优化方法,祝你编程愉快!😊。

java专栏 1212

mysql使用全文检索实现模糊查询再也不使用like+%

前言 mysql在模糊查询数据时使用 “%xx” 会导致索引失效,MySQL 5.6 开始,InnoDB 开始支持全文检索(使用B+tree索引完成模糊查询) 全文检索 1、创建表时创建全文索引语法如下: CREATE TABLE table_name ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, author VARCHAR(200), title VARCHAR(200), content TEXT(500), FULLTEXT full

zouyang920的博客 4633

mysql 全文模糊查找 便捷解决方案

php unicode 工具类 博文链接:https://alxw4616.iteye.com/blog/1886618

告别CPU空转!用STC8的SPI+DMA高效驱动上百颗WS2812B灯珠

本文详细解析了如何利用STC8单片机的SPI+DMA外设高效驱动WS2812B全彩灯珠,解决传统软件延时驱动方式在长灯带应用中的性能瓶颈。通过硬件方案设计、数据格式转换和DMA传输配置,实现高达400Hz的刷新率和低于5%的CPU占用率,适用于大规模灯光项目。

weixin_30847939的博客 394

MySQL 模糊查询再也不用like+%了

例如,对于单词 database 的查询,用户可能希望查询的不仅仅是包含 database 的文档,可能还指那些包含 MySQL、Oracle、RDBMS 的单词,而这时可以使用 Query Expansion 模式来开启全文检索的 implied knowledge。上述两种语句虽然得到的结果是一样的,但从内部运行来看,第二句 SQL 的执行速度更快些,因为第一句 SQL(基于 where 索引查询的方式)还需要进行相关性的排序统计,而第二种方式是不需要的。上述六个索引表构成倒排索引,称为辅助索引表。

IT_1024的博客 890

手把手教你配置MAX96712解串器:从I2C地址分配到PWM帧同步

本文详细解析了MAX96712解串器在自动驾驶视觉链路中的核心配置流程。从I2C地址分配、GMSL2数据流映射到实现多摄像头精准同步的PWM帧同步触发,手把手指导工程师构建高可靠性的图像传输系统,并提供了实用的Linux调试技巧与问题排查思路。

weixin_29297127的博客 920

MySQL 模糊查询再也不用 like+% 了!

我们都知道 InnoDB 在模糊查询数据时使用 “%xx” 会导致索引失效,但有时需求就是如此,类似这样的需求还有很多,例如,搜索引擎需要根基用户数据的关键字进行全文查找,电子商务网站需要根据用户的查询条件,在可能需要在商品的详细介绍中进行查找,这些都不是B+树索引能很好完成的工作。通过数值比较,范围过滤等就可以完成绝大多数我们需要的查询了。但是,如果希望通过关键字的匹配来进行查询过滤,那么就需要基于相似度的查询,而不是原来的精确数值比较,全文索引就是为这种场景设计的。

OOAva的博客 1936

DIY便携式PEMF磁脉冲治疗仪:百元成本自制生物物理疗法设备

脉冲电磁场(PEMF)疗法是一种基于生物物理原理的非侵入性技术,它通过特定频率的电磁脉冲作用于细胞层面,影响细胞膜电位和离子通道活动,从而可能调节细胞代谢与功能。其技术价值在于提供了一种物理干预手段,在健康科技和生物黑客领域被探索用于放松、恢复等场景。实现PEMF的核心是通过信号发生与功率放大驱动电磁线圈产生可控磁场。本文以蓝牙音频模块和智能手机App为切入点,详细解析了如何利用低成本电子元件(如DFRobot XY-WRBT模块和漆包线线圈)构建一个可自定义频率的便携式PEMF设备,涵盖了从电路设计、线圈

weixin_31476015的博客 345

用迅为RK3588开发板DIY无人机飞控:从电路设计到PID调参全记录

本文详细记录了使用迅为RK3588开发板DIY无人机飞控的全过程,从硬件选型、PCB设计到实时系统构建和PID调参。RK3588核心板凭借其强大的AI算力和丰富接口,成为高性能无人机控制解决方案的理想选择。文章还分享了视觉导航系统集成和实际飞行测试经验,为硬件爱好者提供实用参考。

weixin_29053577的博客 425

MySQL模糊查询再也不用 like+% 了!

我们都知道 InnoDB 在模糊查询数据时使用 "%xx" 会导致索引失效,但有时需求就是如此,类似这样的需求还有很多,例如搜索引擎需要根基用户数据的关键字进行全文查找,电子商务网站需要根据用户的查询条件,在可能需要在商品的详细介绍中进行查找,这些都不是 B+树索引能很好完成的工作。通过数值比较,范围过滤等就可以完成绝大多数我们需要的查询了。但是,如果希望通过关键字的匹配来进行查询过滤,那么就需要基于相似度的查询,而不是原来的精确数值比较,全文索引就是为这种场景设计的。目录前言倒排索引全文检索。

qq_67508379的博客 1367

【Bluetooth|蓝牙开发】二、蓝牙开发入门

蓝牙,是一种利用低功率无线电,支持设备短距离通信的无线电技术,能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间进行无线信息交换,蓝牙工作在全球通用的2.4GHz ISM(即工业、科学、医学)频段,使用IEEE802.11协议。

Donge's Blog 1万+

MySQL模糊查询再也不用 like+% 了。。。

我们都知道 InnoDB 在模糊查询数据时使用 "" 会导致索引失效,但有时需求就是如此,类似这样的需求还有很多,例如,搜索引擎需要根基用户数据的关键字进行全文查找,电子商务网站需要根据用户的查询条件,在可能需要在商品的详细介绍中进行查找,这些都不是B+树索引能很好完成的工作。通过数值比较,范围过滤等就可以完成绝大多数我们需要的查询了。但是,如果希望通过关键字的匹配来进行查询过滤,那么就需要基于相似度的查询,而不是原来的精确数值比较,全文索引就是为这种场景设计的。全文索引(Full-Text Search)

wadfdhsajd的博客 1263

uniApp微信小程序:利用live-pusher人脸活体检测功能+完整示例代码,uniapp使用live-pusher直播推流组件实现人脸验证-活体检测,检测人脸中的动作包括眨眼、张嘴、左右摇头动作

UniApp 使用 live-pusher 实现人脸活体检测(附完整源码)uniapp开发微信小程序人脸检测活体检测,在uni-app的微信小程序项目中使用live-pusher实现人脸识别,uniapp使用live-pusher实现模拟人脸识别效果,张张嘴、眨眨眼、向左摇头、向右摇头等动作,免费使用人脸活体检测的插件方案,uniapp小程序怎么免费使用人脸活体,直播推流,UNIAPP微信小程序使用live-pusher实现人脸识别(拍照)功能,在uni-app项目中实现人脸识别,既使用uni-app中的l

✅ 精选推荐文章 3013

uniapp [安卓苹果App端] - 详细实现自定义水印相机功能,调用手机摄像头打开相机并在周围悬挂自定义水印,使用相机拍照后添加水印文字或样式,uniapp APP端水印相机完整源码,兼容强大可靠

uni-app,安卓Android,苹果ios,安卓app端,苹果App端,uniapp苹果app,水印相机,uniapp水印相机,Uniapp安卓app实现水印相机,uniapp苹果ios水印相机,打开系统相机拍照添加水印,地点打卡相机,水印相机(水印照片,图片加水印),uniapp自定义水印相机,制作水印相机给图片添加水印并且保存图片至本地,uniapp拍照图片加水印,水印相机功能,手机调起摄像头拍照时自动插入文字、图片动态水印效果,支持水印显示拍摄者当前城市定位、自由调整水印大小和位置,手机拍照时

🏆 前端领域优质创作者 1万+

MySQL模糊查询再也不用 like+% 了

分享一篇InnoDB 全文检索相关的文章,拓展一下 MySQL 知识点。InnoDB 的全文检索在一些简单的搜索场景下还是比较实用的,可以替代 like+%,并且不需要额外依赖其他服务...

hnjsjsac的博客 644

从 Chat 提示词到可运行 Fiori 应用,ADT for VS Code 正在把 RAP 开发带进 Agent 时代

本文探讨了在VS Code中使用AI辅助进行ABAP RAP开发的新模式。文章指出,传统RAP开发需要手工创建数据库表、CDS视图、行为定义等十多个关联对象,命名和关联关系容易出错。现在通过GitHub Copilot Agent Mode配合ADT MCP Server,开发者可用自然语言描述业务场景直接生成完整的RAP业务对象。这种生成式开发的核心价值在于:1)通过标准化工具接口(MCP)连接ABAP后端,确保生成符合规范的RAP对象;2)能正确处理多实体组合场景下的命名一致性和关联关系;3)保持生成结

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 85
上一篇: 阿里面试官问我:如何设计登录接口,十分钟内连续登录5次失败,需要等待30分钟才能登录
下一篇: 关于代码质量退化的思考
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值