我知道这个问题已经被问过好几次了。但是,让我解释一下。
我有一个包含 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/