竹永康在科锐待岗第3天工作总结

今日研读了《高性能MySQL》一书中的第 7.10 章节:MySQL高级特性之全文索引,从中学习到了一些专业技能知识。总结如下。

文章目录

  • 全文索引
    • MyISAM全文索引
    • 自然语言的全文索引
    • 布尔全文索引
    • 全文索引的限制和替代方案
    • 全文索引的配置和优化

全文索引

全文索引是为 “通过关键字的匹配来进行相似度的查询过滤” 的场景而设计的。

MyISAM全文索引

MyISAM的全文索引作用对象是一个"全文集合",这可能是某个数据表的一列,也可能是多个列。具体的,对数据表的某一条记录,MySQL会将需要索引的列全部拼接成一个字符串,然后进行索引。

MyISAM对全文索引的支持有很多的限制,例如表级别锁对性能的影响、数据文件的崩溃、崩溃后的恢复等,这使得MyISAM的全文索引对于很多应用场景并不合适。

MyISAM的全文索引是一类特殊的 B-Tree 索引,共有两层。第一层是所有关键字,然后对于每一个关键字的第二层,包含的是一组相关的"文档指针",全文索引不会索引对象中的所有词语,它会根据如下规则过滤一些词语:

  • 停用词列表中的词不会被索引。默认的停用词根据通用英语的使用来设置,可以使用参数 ft_stopword_file 指定一组外部文件来使用自定义的停用词。
  • 对于长度大于 ft_min_word_len 的词语和长度小于 ft_max_word_len 的词语,都不会被索引。

全文索引并不会存储关键字具体匹配在哪一行,如果需要根据不同的列来进行组合查询,那么不需要根据每一列来建立多个这类索引。这也意味着不能在像 MATCH AGAINST 的子句中指定哪个列的相关性更重要:
通常构建一个网站的搜索引擎是需要这样的功能,例如,用户希望优先搜索出那些在标题中出现过的文档对象。如果需要这样的功能,则需要编写更复杂的查询。

自然语言的全文索引

自然语言搜索引擎将计算每一个文档对象和查询的相关度。相关度是基于匹配的关键词个数,以及关键词在文档中出现的次数。注意是:在整个索引中出现次数越少的词语,匹配时的相关度就越高。相反,非常长常见的单词将不会被搜索,即使不再停用词列表中出现,如果一次词语在超过50%的记录中都出现了,那么自然语言搜索将不会搜索这类词语。

如果进行全文搜索的数据集过小,可能无法返回结果。原因在于,每个搜索关键词都可能在一半以上的记录里面出现过。

全文索引的语法和不同查询略有不同。可以根据 WHERE 子句中的 MATCH(columns) AGAINST('keyword') 来区分查询是否使用全文索引,示例语句如:

SELECT id, title, RIGHT(description, 25), MATCH(title, description) AGAINST('factory casualties') AS relevance
FROM sakila.film_text
WHERE MATCH(title, description) AGAINST('factory casualties');

上面的语句中,MySQL将搜索词 ‘factory casualties’ 分成两个独立的关键词在 title 和 description 字段组成的全文索引上进行搜索。搜索结果将根据关键词的相似度排序列出(和普通查询不同,这类查询自动按照相似度进行排序。注意,在使用全文索引进行排序的时候,MySQL无法在使用索引排序)。

函数 MATCH() 将返回关键词匹配的相关度,是一个浮点数字。在一个查询中使用两次 MATCH() 函数并不会有额外的消耗,MySQL会自动识别并只进行一次搜索。不过,如果将 MATCH() 函数放到 ORDER BY 子句中,MySQL将会使用文件排序。

在 MATCH() 函数中指定的列必须和在全文索引中指定的列完全相同,否则就无法使用全文索引。这是因为全文索引不会记录关键字是来自那一列的(这也意味着无法使用全文索引来查询某个关键字是否在某一列中存在)。

布尔全文索引

在布尔搜索中,用户可以自定义某个被搜索的词语的相关性。布尔搜索通过停用词列表过滤掉哪些"噪声"词,除此之外,布尔搜索还要求搜索关键词长度必须大于 ft_min_word_len,同时小于 ft_max_word_len。与自然语言的全文索引不同,布尔全文索引的搜索结果是未经排序的。

布尔搜索通常一些前缀修饰符来定制搜索:

  • dinosaur: 包含 “dinosaur” 的行 rank 值更高;
  • ~dinosaur: 包含 “dinosaur” 的行 rank 值更低(符号 “~” 通常表示取反);
  • +dinosaur: 行记录必须包含 “dinosaur”;
  • -dinosaur: 行记录必须不包含 “dinosaur”;
  • dino*: 包含以 “dino” 开头的单词的行 rank 值更高。

还可以使用其他的操作,例如使用括号分组,构建一些更复杂的搜索查询。这类似于编程语言中的正则表达式模式。示例语句,搜索出既包含词 “factory” 又包含 “casualties” 的记录:

SELECTid, title, RIGHT(description, 25)
FROM sakila.film_text
WHERE MATCH(title, description) AGAINST('+factory +casualties' IN BOOLEAN MODE);

类似的还可以在查询中使用括号进行"短语搜索",让返回结果精确匹配指定的短语:

SELECT id, title, RIGHT(description, 25)
FROM sakila.film_text
WHERE MATCH(title, description) AGAINST('"spirited casualties"' IN BOOLEAN MODE);

短语搜索的速度会比较慢。只使用全文索引是无法判断是否精确匹配短语的,通常还需要查询原文确定记录中是否包含完整的短语。由于需要进行会表过滤,索引速度会很慢。要完成上面的查询,MySQL需要先从索引中找出所有同时包含 “spirited” 和 “casualties” 的索引条目,然后取出这些记录再判断是否是精确匹配短语。

全文索引的限制和替代方案

MySQL全文索引中只有一种判断相关性的方法:词频。索引也不会记录索引词在字符串中的位置,索引位置也有无法用在相关性上。MySQL的全文索引也没有提供其它可选的相关性排序算法。

数据量的大小也是一个问题:MySQL的全文索引只有全部在内存中的时候,性能才非常好。如果内存无法状态全部索引,那么搜索速度可能会非常慢(尤其在使用精确短语搜索时)。相比其他的索引类型,"写"操作的代价会更大:

  • 修改一段文本中的 100 个单词,需要 100 次索引操作,而不是一次。
  • 一般来说列长度并不会太影响其它索引类型,但是如果是全文索引,三个单词的文本和 10000 个单词的文本,性能可能会相差几个数量级。
  • 全文索引会有更多的碎片,可能需要做更多的 OPTIMIZE TABLE 操作。

全文索引还会影响查询优化器的工作:

  • 如果查询中使用了 MATCH AGAINST 子句,而对应列上又有可用的全文索引,那么MySQL就一定会使用这个全文索引,即使有其它的更优的索引可用(这里包含连续条件判断)。
  • 全文索引只能用作全文搜索匹配。其它任何操作,如 WHERE 条件比较,都必须在MySQL完成全文搜索返回记录后才能进行。
  • 全文索引不存储索引列的实际值。也就意味着其不可能用作索引覆盖扫描。
  • 除了相关性排序,全文索引不能用作其它的排序。如果查询需要做相关性以外的排序操作,都需要使用文件排序。

这些限制影响着查询,下面给出一个直观的例子(字段 content 上有全文索引,字段 author 上有普通索引):

...
WHERE MATCH(content) AGAINST ('High Performance MySQL')
AND author = 123;

即使这里 author 字段创建了普通索引,也依然不会被使用。因为这里使用了 MATCH AGAINST,而且恰好上面有全文索引,所以MySQL优先选择使用全文索引,即先搜索所有的文档,查找是否有包含关键词的文档,然后返回记录看看作者是否是 123。所以这里也就没有使用 author 字段上的索引。

一个替代方案是将 author 列包含到全文索引中。当然不是直接包含,在 author 列的值前面附上一个不常见的前缀,然后将这个带前缀的值存放到一个单独的 filters 列中,并单独维护该列(也与可以使用触发器来做维护工作):

...
WHERE MATCH(content, filters)
AGAINST ('High Performance MySQL +author_id_123' IN BOOLEAN MODE);

在这个案例中,如果 author 列的选择性非常高,那么MySQL能够根据作者信息很快地将需要过滤的文档记录限制在一个很小的范围内,这个查询的效率也就会非常好。如果 author 列的选择性很低,那么这个替代方案的效率会比前面的那个更糟,所以使用的时候要谨慎。

虽然只有MyISAM表支持全文索引,但如果仍然希望使用InnoDB或其它引擎,可以将原表复制到一个备库,再将备库上的表改成MyISAM并建上相应的全文索引。如果不希望在另一个服务器上完成查询,还可以对表进行垂直拆分,将需要索引的列放到一个单独的MyISAM表中。

全文索引的配置和优化

全文索引的日常维护通常能够大大提升性能。“双B-Tree” 的特殊结构、在某些文档中比其他文档要包含多得多的关键字,这都使得全文索引比起普通索引有更多的碎片问题。所以需要经常使用 OPTIMIZE TABLE 来较少碎片。如果应用是 I/O 密集型的,那么定期地进行全文索引重建可以让性能提升很多。

如果希望全文索引能够高效地工作,还需要保证索引缓存足够大,从而保证所有的全文索引都能够缓存在内存中。通常,可以为全文索引设置单独的键缓存(Key cache),保证不会被其他的索引缓存挤出内存。

提供一个好的停用词列表;忽略一些太短的单词(索引单词的最小长度可以通过参数 ft_min_word_len 配置。修改该参数可以过滤更多的单词,让查询速度更快,但是也会降低精确度)。停用词表和允许最小词长都可以通过减少索引词语来提升全文索引的效率,但是同时也会降低搜索的精确度。

这些都需要根据实际的应用场景找到合适的平衡点。如果希望同时获得好的性能和好的搜索质量,那么需要自己定制这些参数。一个好的办法是通过日志系统来研究用户的搜索行为,看看一些异常的查询,包括没有结果返回的查询或者返回过多结果的用户查询。通过这些用户行为和被搜索的内容来判断应该如何调整索引策略。

另外要注意,当调整 “允许最小词长” 后,需要通过 OPTIMIZE TABLE 来重建索引才会生效。另一个参数 ft_max_word_len 也一样。

当向一个有全文索引的表中导入大量数据的时候,最好通过命令 DISABLE KEYS 来禁用全文索引,然后在导入结束后使用 ENABLE KEYS 来建立全文索引。因为全文索引的更新时一个消耗很大的操作,所以上面的细节会帮你节省大量的时间。另外,这样还顺便为全文索引做了一次碎片整理工作。

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

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

相关文章

玻尔兹曼常数

参考: https://vibaike.com/216369/ 萨尔茨曼常数(kB 或 k)是将气体中粒子的平均相对动能与气体的热力学温度相关联的比例因子。 它出现在开尔文和气体常数的定义中,出现在普朗克黑体辐射定律和玻尔兹曼熵公式中,并用…

3D视觉专用名词概念解释,深度图、点云图、IR图、RGB图像

🌞欢迎来到深度学习的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 🙏作者水平很有限,如果发现错误&#xff…

【PyTorch】PyTorch之Tensors属性篇

文章目录 前言一、Tensors1、is_tensor2、is_storage3、is_complex4、is_conj5、is_floating_point6、is_nonzero7、set_default_dtype8、get_default_dtype9、set_default_device10、set_default_tensor_type11、torch.numel12、set_printoptions13、set_flush_denormal 前言 …

JAVA电商平台 免 费 搭 建 B2B2C商城系统 多用户商城系统 直播带货 新零售商城 o2o商城 电子商务 拼团商城 分销商城

涉及平台 平台管理、商家端(PC端、手机端)、买家平台(H5/公众号、小程序、APP端(IOS/Android)、微服务平台(业务服务) 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis …

Debian系统写Mysql时中文出现乱码无法定入的问题解决方案

原因是操作系统可能精简安装,没有GBK字符集,只有UTF8在转换或使用的时候有问题。 使用locale -a查看系统支持的字符集。正常的比较全的字符集的操作系统如下: 有问题的操作系统字符集如下: 解决方案: 步骤1&#…

智能小车(八)ros实现将智能小车数据通过TCP/IP发送到上位机网关

ros实现将智能小车数据通过TCP/IP发送到上位机网关 这里主要注意: 将浮点型数据*1000转换成int型数据然后分字节储存(另取一个字节作为符号位)。没有用struct.pack进行字节流打包,原因是不同平台,字节流的打包浮点型数据不一样&am…

力扣(leetcode)第830题较大分组的位置(Python)

830.较大分组的位置 题目链接:830.较大分组的位置 在一个由小写字母构成的字符串 s 中,包含由一些连续的相同字符所构成的分组。 例如,在字符串 s “abbxxxxzyy” 中,就含有 “a”, “bb”, “xxxx”, “z” 和 “yy” 这样的…

C++ //练习 2.11 指出下面的语句是声明还是定义:

C Primer(第5版) 练习 2.11 练习 2.11 指出下面的语句是声明还是定义: ( a ) extern int ix 1024; ( b ) int iy; ( c ) extern int iz; 环境:Linux Ubuntu(云服务器) 工具:vim 解释 ( …

time-to-event数据的参考资料

目录 一、书籍推荐 二、方法论文章 Introductory/Overview Articles Censoring Non-parametric survival methods Semi-parametric survival methods Parametric survival methods Time-Varying Covariates Competing risk analysis Analysis of clustered data and fra…

基于Java+SSM框架的智慧医疗问诊管理系统【附源码】

基于JavaSSM框架的智慧医疗问诊管理系统详细设计和实现【附源码】 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各…

高效视频剪辑:视频合并让视频焕然一新,添加背景音乐更动听

随着社交媒体和数字内容的普及,视频剪辑已成为一项常用的技能。除了基本的剪辑技巧外,添加合适的背景音乐也是提升视频质量的方法。下面来看云炫AI智剪的高效视频剪辑技巧——如何批量合并视频,添加动听的背景音乐。 视频合并后的效果展示&a…

Interface 接口

/* * 语法1:使用interface关键字定义 * 语法2:接口中,允许定义“抽象方法”,public 和 abstract关键字可以省略 * 语法3:接口中,允许定义“默认方法” * 语法4:实现类通过implements关键字实现接…

What is `@Repository` does?

Repository 是Spring注解,标识数据访问层组件(DAO, Data Access Object) 当一个类被标记为 Repository 时: 1、组件扫描与自动代理: Spring通过组件扫描(Component Scan)机制发现带有 Reposit…

编程语言的比较—c语言,c++与java,c#的比较

c语言是历史悠久的语言,不仅可以开发应用程序,还可以用来编写操作系统。如果对接近硬件的部分进行操作,c语言是不二之选。 c语言是c语言中增加面向对象功能的编程语言。通常情况下,c可以编译c语言编写的代码。c广泛应用于微型计算…

【AI绘画+本地部署】基于krita的AI绘画(含windows一键整合包)

comfyuikrita所有相关资源整合包(无需下载后面链接)百度网盘:https://pan.baidu.com/s/1iwNRpdTaD26YbzSDm6WLDA?pwdbur8 –来自百度网盘超级会员V4的分享 krita绘画软件官网地址 https://krita.org/en/download/krita-desktop/ krita-ai-diffusion 插件&#xff…

数据库:园林题库软件(《城市绿地系统规划》答题卷四)

《城市绿地系统规划》答题卷四 填空题 1、生产绿地是指为城市绿化提供苗木、花草、种子的苗圃、草圃等圃地,是为城市绿化服务的生产、科研实验绿地。 园林苗圃的规模按照其用地面积来划分,可分为大型苗圃、中型苗圃、小型苗圃三类。 2、防护绿地是出…

P1451 求细胞数量——深搜、广搜

求细胞数量 题目描述 一矩形阵列由数字 0 0 0 到 9 9 9 组成,数字 1 1 1 到 9 9 9 代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。 输入格式 第一行两个整数代表矩阵大小 n n n 和…

计算机网络-ACL访问控制列表

上一篇介绍NAT时候就看到了ACL这个东西了,这个是什么意思?有什么作用呢? 一、ACL访问控制列表 访问控制列表 (ACL, Access Control List)是由一系列permit或deny语句组成的、有序规则的列表。ACL是一个匹配工具,能够对报文进行匹配…

鸿蒙原生应用/元服务实战-AGC团队账户

多人及内外结合去开发运营鸿蒙原生应用元服务时,需要用到团队账户,AGC提供了强大的团队角色与权限分工能力。 团队帐号是开发者联盟为实名开发者提供的多个成员帐号登录与权限管理服务。当前团队帐号支持成员参与应用市场(付费推广、应用内付…

设备树(1)-设备树是什么?设备树基础概念及语法

1.简介 设备树:device tree DTS:设备树源码文件,采用树形结构描述板级信息,例如IIC、SPI等接口接了哪些设备 DTSI:设备树头文件,描述SOC级信息,例如几个CPU、主频多少、各个外设控制信息等 DTB…