mysql match() against() 或 match() against() 慢

mysql match() agains() OR match() against() SLOW

我 table 有很多行 (~2M)。 当我搜索它时喜欢

SELECT * FROM product WHERE 
MATCH(name) AGAINST('+some' '+word' IN BOOLEAN MODE)

它像魅力一样工作,在不到 0.5 秒内找到我需要的东西。

但是当我像这样搜索 2 组单词时

SELECT * FROM product WHERE 
MATCH(name) AGAINST('+some' '-word' IN BOOLEAN MODE) 
OR 
MATCH(name) AGAINST('+something' '-other' IN BOOLEAN MODE)

搜索有时需要超过一分钟。

我预计它会慢 2 倍(搜索 2 次),也许会慢一些(您仍然需要比较结果并删除重复项,但如果结果很少,应该不会花很长时间),但是不会再长了。添加 OR 后它的工作速度比 LIKE "%...%" OR LIKE "%...%"

谁能告诉我我做错了什么?

不幸的是,全文索引 have some limitations,无法正确合并两个独立全文搜索的结果就是其中之一:

The Index Merge optimization algorithm has the following known limitations:

  • [...]
  • Index Merge is not applicable to full-text indexes.

幸运的是,全文搜索可能更复杂,因此您可以自己合并搜索。您的第二个查询可以写成单个搜索,使用:

SELECT * FROM product WHERE 
MATCH(name) AGAINST('(+something -other) (+some -word)' IN BOOLEAN MODE)

这定义了两个搜索集,如果两个 (...) 中的任何一个匹配都可以 - 这是一个 or.

或者,您可以使用 union 而不是 or,这允许 MySQL 实际上 运行 两个独立的全文搜索,然后合并两个结果,这基本上就是您的想法:

SELECT * FROM product WHERE 
MATCH(name) AGAINST('+some -word' IN BOOLEAN MODE) 
UNION 
SELECT * FROM product WHERE 
MATCH(name) AGAINST('+something -other' IN BOOLEAN MODE)

这也适用于更复杂的情况,例如合并对不同列的搜索,但如果您想做 or.

之外的其他事情,将不会那么容易