前言
最近在学习和了解 MySQL 8 自带的全文搜索功能。自己在看资料的时候顺便翻译了一下,希望对大家有用。(章节序号可能有所差异,因为官方文档会不定期更新)
官方原文链接如下:《Fine-Tuning MySQL Full-Text Search》
MySQL的全文搜索功能几乎没有用户可调参数。如果您有 MySQL 源代码分发,则可以对全文搜索行为施加更多控制,因为某些更改需要修改源代码。参阅 Installing MySQL from Source。
全文搜索经过仔细调整,以确保有效性。在大多数情况下,修改默认行为实际上会降低有效性。除非您知道自己在做什么,否则不要更改MySQL源代码。
本节中描述的大多数全文变量必须在服务器启动时设置。需要重新启动服务器才能更改它们;在服务器运行时无法修改它们。
某些变量更改要求您在表中重新生成 FULLTEXT 索引。本节稍后将提供有关执行此操作的说明。
配置最小和最大字长
配置自然语言搜索阈值
修改布尔全文搜索运算符
字符集修改
重建 InnoDB 全文索引
优化 InnoDB 全文索引
重建 MyISAM 全文索引
配置最小和最大字长
要索引的单词的最小和最大长度由 InnoDB 搜索索引的 innodb_ft_min_token_size 和 innodb_ft_max_token_size 以及 MyISAM 的 ft_min_word_len 和 ft_max_word_len 定义。
注意
最小和最大字长全文参数不适用于使用 ngram 解析器创建的 FULLTEXT 索引。ngram 字长大小由 ngram_token_size 选项定义。
更改这些选项中的任何一个后,请重新生成 FULLTEXT 索引以使更改生效。例如,要使两个字符的单词可搜索,可以将以下行放在选项文件中:
[mysqld] innodb_ft_min_token_size=2 ft_min_word_len=2
然后重新启动服务器并重新生成 FULLTEXT 索引。
对于 MyISAM 表,请注意以下用于重建 MyISAM 全文索引的说明中有关 myisamchk 的注释。
配置自然语言搜索阈值
对于 MyISAM 搜索索引,自然语言搜索的50%阈值由所选的特定加权方案决定。要禁用它,请在 storage/myisam/ftdefs.h 中查找以下行:
#define GWS_IN_USE GWS_PROB
将该行更改为:
#define GWS_IN_USE GWS_FREQ
然后重新编译 MySQL。在这种情况下,无需重新生成索引。
注意
通过进行此更改,您将严重降低 MySQL 为 MATCH() 函数提供足够相关性值的能力。如果您确实需要搜索此类常用词,最好改用 IN BOOLEAN MODE 进行搜索,因为它不遵守 50% 的阈值。
修改布尔全文搜索运算符
若要更改用于对 MyISAM 表进行布尔全文搜索的运算符,请设置 ft_boolean_syntax 系统变量。(InnoDB 没有等效的设置。) 可以在服务器运行时更改此变量,但您必须具有足够的权限来设置全局系统变量 (参阅 System Variable Privileges). 在这种情况下,不需要重新生成索引。
字符集修改
对于内置的全文分析器,可以通过多种方式更改被视为单词字符的字符集,如以下列表所述。进行修改后,重新生成包含任何 FULLTEXT 索引的每个表的索引。假设您要将连字符 ('-') 视为单词字符。使用以下方法之一:
修改MySQL数据库源码:位置在 storage/innobase/handler/ha_innodb.cc (对于InnoDB类型的表), 或者在 storage/myisam/ftdefs.h (对于 MyISAM类型的表), 请参阅 true_word_char()和 misc_word_char() 宏。将“-”添加到其中一个宏并重新编译 MySQL。
修改字符集文件:这不需要重新编译。true_word_char() 宏使用“字符类型”表将字母和数字与其他字符区分开来。您可以在<ctype><map>其中一个字符集 XML 文件中编辑数组的内容,以指定“-”是“字母”。 然后对 FULLTEXT 索引使用给定的字符集。有关<ctype><map>数组格式的信息,参阅 Character Definition Arrays.
为索引列使用的字符集添加新的排序规则,并更改列以使用该排序规则。有关添加排序规则的一般信息,参阅 Adding a Collation to a Character Set. 对于特定于全文索引的示例,参阅 《12.9.7 为全文索引添加自定义排序》。
重建 InnoDB 全文索引
要使更改生效,必须在修改以下任何全文索引变量后重新生成 FULLTEXT 索引:
innodb_ft_server_stopword_table;
innodb_ft_user_stopword_table;
其中,修改 innodb_ft_min_token_size, innodb_ft_max_token_size, 或者 ngram_token_size 需要重启服务。
要为 InnoDB 表重新生成 FULLTEXT 索引,请使用带有 DROP INDEX 和 ADD INDEX 选项的 ALTER TABLE 删除并重新创建每个索引。
优化 InnoDB 全文索引
在具有全文索引的表上运行 OPTIMIZE TABLE 会重建全文索引,删除已删除的文档 ID 并尽可能合并同一单词的多个条目。
要优化全文索引,请启用 innodb_optimize_fulltext_only 并运行 OPTIMIZE TABLE。
mysql> set GLOBAL innodb_optimize_fulltext_only=ON; Query OK, 0 rows affected (0.01 sec)
mysql> OPTIMIZE TABLE opening_lines; +--------------------+----------+----------+----------+ | Table | Op | Msg_type | Msg_text | +--------------------+----------+----------+----------+ | test.opening_lines | optimize | status | OK | +--------------------+----------+----------+----------+ 1 row in set (0.01 sec)
为了避免大型表上的全文索引的重新生成时间过长,可以使用 innodb_ft_num_word_optimize 选项分阶段执行优化。innodb_ft_num_word_optimize 选项定义每次运行 OPTIMIZE TABLE 时优化的字数。默认设置为 2000,这意味着每次运行 OPTIMIZE TABLE 时都会优化 2000 个单词。后续的 OPTIMIZE TABLE 操作从前面的 OPTIMIZE TABLE 操作结束的位置继续。
重建 MyISAM 全文索引
如果修改影响索引的全文变量(ft_min_word_len、ft_max_word_len或ft_stopword_file),或者更改非索引字文件本身,则必须在进行更改并重新启动服务器后重新生成 FULLTEXT 索引。
要重建 MyISAM 表的 FULLTEXT 索引,只需执行 QUICK 修复操作即可:
mysql> REPAIR TABLE tbl_name QUICK;
或者,使用刚才描述的 ALTER TABLE。在某些情况下,这可能比修复操作更快。
必须修复包含任何 FULLTEXT 索引的每个表,如上所示。 否则,对表的查询可能会产生不正确的结果,并且对表的修改会导致服务器将表视为已损坏并需要修复。
如果使用 myisamchk 执行修改 MyISAM 表索引的操作(如修复或分析),则除非另有指定,否则将使用最小字长、最大字长和非索引字文件的默认全文参数值重新生成 FULLTEXT 索引。这可能会导致查询失败。
出现此问题的原因是这些参数只有服务器知道。它们不存储在 MyISAM 索引文件中。如果修改了服务器使用的最小或最大字长或非索引字文件值,请为 myisamchk 指定与用于mysqld 相同的ft_min_word_len,ft_max_word_len和ft_stopword_file值,以避免此问题。
例如,如果您已将最小字长设置为 3,则可以使用 myisamchk 修复表,如下所示:
myisamchk --recover --ft_min_word_len=3 tbl_name.MYI
要确保 myisamchk和服务器对全文参数使用相同的值,请将每个值放在选项文件的 [mysqld] 和 [myisamchk] 部分中:
[mysqld] ft_min_word_len=3 [myisamchk] ft_min_word_len=3
使用 myisamchk进行 MyISAM 表索引修改的替代方法是使用 REPAIR TABLE、ANALYZE TABLE、OPTIMIZE TABLE 或 ALTER TABLE 语句。这些语句由服务器执行,服务器知道要使用的正确全文参数值。