MySQL部分单词匹配结合了MATCH ... AGAINST和LIKE作为备份

时间:2018-10-12 10:49:57

标签: mysql sql indexing query-optimization

布尔型模式下MATCH...AGAINST的MySQL文档说的类似“星号用作截断(或通配符)运算符。与其他运算符不同,它附加在受影响的单词后面。如果单词匹配,则匹配以*运算符之前的单词开头。”这意味着您只能将其用于匹配单词的开头。我希望能够尽可能高效地进行搜索,有时我搜索的单词是目标字符串中间的部分单词。我试图避免在不需要时进行全表扫描。

是否可以将MATCH...AGAINST语法与备份WHERE foo LIKE '%bar%组合在一起?

例如,我有下表(为简洁起见,省略了很多字段):

CREATE TABLE `tours` (
  `tourId` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
  `tourName` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`tourId`),
  FULLTEXT KEY `ft_tourId_tourName` (`tourName`,`tourId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

我希望能够在单个查询中同时对tourId和tourName进行搜索,仅在绝对必要时才进行全表扫描。

是否可以执行这样的操作,将MATCH...AGAINSTLIKE结合在一起,而无需进行全表扫描:

SELECT
    *
FROM
    tap.tourdetails
WHERE
    MATCH(tourId, tourName) AGAINST('dc10*' IN BOOLEAN MODE)
    OR tourId LIKE '%dc10%' OR tourName LIKE '%dc10%' ORDER BY tourName;

目前,即使MATCH...AGAINST中实际上匹配了“ dc10 *”,上述内容也进行了全表扫描。如果MATCH失败,我只想使用LIKE(并且需要全表扫描)。可能?替代解决方案?

1 个答案:

答案 0 :(得分:0)

假设您希望找到xyzdc10

  • MATCH不会提交xyzdc10,但LIKEs会提交。
  • LIKE带有 Leading 通配符,需要进行全表扫描。
  • 您正在使用OR

进行表扫描。

相反,如果您只想 dc10开头的单词,请摆脱LIKEsMATCH完成所有工作,并做到了快。

FULLTEXT索引将列分成单词,并搜索单词。 LIKE不;相反,它必须扫描每个字符串。初始通配符不会使索引LIKE受益。