MySQL全文搜索,但使用LIKE

时间:2011-04-07 10:56:30

标签: mysql sql

我最近在一张表中进行了一些字符串搜索,其中有大约50k字符串,相当大,我会说但不是那么大。我正在为“搜索结果”之类的东西做一些嵌套查询。我正在使用LIKE语句来获取搜索关键字的匹配项。

我遇到了MySQL的全文搜索,我尝试过,因此我在str列添加了全文索引。我知道全文搜索不适用于虚拟创建的表,甚至不适用于Views,因此具有子选择的查询将不适合。我提到过我正在进行嵌套查询,例如:

SELECT s2.id, s2.str 
FROM 
    (
    SELECT s1.id, s1.str 
    FROM 
        (
         SELECT id, str 
         FROM strings 
         WHERE str LIKE '%term%'
         ) AS s1 
    WHERE s1.str LIKE '%another_term%'
    ) AS s2 
WHERE s2.str LIKE '%a_much_deeper_term%';

这实际上还没有应用于任何代码,我只是做了一些测试。此外,通过使用Sphinx(性能明智)可以很容易地实现这样的搜索字符串,但让我们考虑Sphinx不可用,我想知道它在纯SQL查询中如何运行良好。在没有添加全文的表上运行此查询大约需要2.97 secs。 (取决于搜索词)。但是,在具有全文添加到str列的表上运行此查询已完成,如104ms,这很快(我认为?)。

我的问题很简单,使用 LIKE 是否有效,或者在通常我们使用 MATCH <添加全文的表格中使用它是一个好习惯/ strong>和反对声明?

谢谢!

1 个答案:

答案 0 :(得分:1)

在这种情况下,您不一定需要子选择。你可以使用:

SELECT id, str
FROM item_strings
WHERE str LIKE '%term%'
   AND str LIKE '%another_term%'
   AND str LIKE '%a_much_deeper_term%'

...但也提出了一个很好的问题:排除行的顺序。我猜MySQL很聪明,可以假设最长的术语是最具限制性的,所以从a_much_deeper_term开始,它将消除大部分记录,然后仅在几行上执行附加比较。 - 与此相反,如果你从term开始,你可能会得到许多可能的记录,然后你必须将它们与术语的st进行比较。

有趣的是,您可以使用原始子选择示例强制进行比较的顺序。这使得有机会根据更长的汉字来决定哪个术语是最具限制性的,但是例如:

  • 辅音与元音的比例
  • 这个词中最长的辅音链
  • 单词中最常用的元音

...等。您还可以根据您正在处理的文本信息类型应用一些启发式

修改

这只是一种预感,但可以将LIKE应用于全文索引中的words。然后将这些行与索引进行匹配,就好像你已经为完整单词进行了分类一样。

我不确定这是否真的已经完成,但是对MySQL人来说是一件很聪明的事情。另请注意,只有在全文搜索中实际存在所有可能的事件时才能使用此理论。为此你需要:

  • 您的搜索模式必须至少为最小字长的大小。 (如果您正在搜索示例%id%,那么它也可以是3个字母单词的一部分,默认情况下将其排除在FULLTEXT索引之外。
  • 您的搜索模式不得是任何列出的排除字的子字符串,例如:和,等等。
  • 您的图案不得包含任何特殊字符。