mysql - 如何快速地在 MySQL 中的多列中进行全文搜索?

标签 mysql full-text-search myisam full-text-indexing

我知道这个问题已经被问过好几次了。但是,让我解释一下。

我有一个包含 450k 用户记录的表(id、名字、姓氏、地址、电话号码等)。 我想按名字和/或姓氏搜索用户。

我使用了这些查询:

SELECT * FROM correspondants WHERE nom LIKE 'Renault%' AND prénom LIKE 'r%';

SELECT * FROM correspondants WHERE CONCAT(nom, CHAR(32), prénom= LIKE 'Renault r%';

效果很好,但持续时间太长(1.5 秒)。这是我的问题。

为了修复它,我尝试在“nom”和“prénom”这两个列上使用 MATCH 和 AGAINST 以及全文索引:

SELECT * FROM correspondants WHERE MATCH(nom, prénom) AGAINST('Renault r');

它非常快(0,000 s ..)但是结果很糟糕,我没有得到我应该得到的。

例如,使用 LIKE 函数,结果是:

88623   RENAULT Rémy
91736   RENAULT Robin
202269  RENAULT Régine

(3 个结果)。

和 MATCH/AGAINST :

327380  RENAULT Luc
1559    RENAULT Marina
17280   RENAULT Anne
(...)
88623   RENAULT Rémy
91736   RENAULT Robin
202269  RENAULT Régine
(...)
436696  SEZNEC-RENAULT  Helene
(...)

(115 个结果!)

使用“AND”搜索对两列进行快速高效的文本搜索的最佳方法是什么? (以及索引呢)

最佳答案

全文搜索不像 LIKE 字符串比较那样进行模式匹配。全文搜索只搜索完整的单词,而不是像 r% 这样的片段。

还有一个字的最小大小,由 ft_min_word_len 配置变量控制。为避免使全文索引过大,它不会索引小于该变量的词。因此,当您搜索时,短词会被忽略,因此 r 会被忽略。

全文索引也无法在特定位置(如字符串开头)搜索单词。因此,您可能会在字符串的中间找到对 renault 的搜索。

要解决这些问题,您可以执行以下操作:

SELECT * FROM correspondants WHERE MATCH(nom, prénom) AGAINST('Renault')
  AND CONCAT(nom, CHAR(32), prénom) LIKE 'Renault r%';

这将使用全文索引来查找 450,000 行中字符串中某处包含单词 renault 的一小部分。然后搜索中的第二项将在没有索引帮助的情况下完成,但仅针对与第一项匹配的行子集。

关于mysql - 如何快速地在 MySQL 中的多列中进行全文搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57647175/

相关文章:

php - 使用 MySQL 从表中获取特定列表,然后获取剩余列表

mysql - InnoDB 二级索引包括值而不是指向 PK 的指针,这怎么够了?

mysql - 创建 SQL 查询

mysql - 捕捉时间范围

MySQL 在 MATCH AGAINST 中使用 GROUP_CONCAT 字段

MYSQL FULLTEXT 搜索不适用于连字符 '-' 和加号 '+'

mysql innodb 和 myisam 之间的更新时间

php - 超过 1200 万行的表在性能问题中运行

php - 连接两个表并使用单个查询显示第二个表行数据,以逗号分隔第一个表行

php - MySQL多关键字搜索算法