什么是全文搜索与LIKE

时间:2008-10-22 07:00:40

标签: sql full-text-search sql-like

我刚读了一篇在SQL中提到“全文搜索”的帖子。

我只是想知道FTS和LIKE之间的区别是什么。我确实阅读了几篇文章,但找不到任何解释得很好的文章。

6 个答案:

答案 0 :(得分:144)

一般来说,在“精确”和“召回”之间存在权衡。高精度意味着呈现较少的无关结果(无误报),而高召回意味着缺少较少的相关结果(无假阴性)。使用LIKE运算符可以提供100%的精度,并且不会让步。全文搜索工具为您提供了很大的灵活性,可以调低精度以便更好地调用。

大多数全文搜索实现都使用“反向索引”。这是一个索引,其中键是单个术语,关联值是包含术语的记录集。优化全文搜索以计算这些记录集的交集,并集等,并且通常提供排序算法来量化给定记录与搜索关键字匹配的强度。

SQL LIKE运算符效率极低。如果将其应用于未索引的列,则将使用完整扫描来查找匹配项(就像未索引字段上的任何查询一样)。如果列已编制索引,则可以对索引键执行匹配,但效率远低于大多数索引查找。在最坏的情况下,LIKE模式将具有需要检查每个索引键的前导通配符。相比之下,许多信息检索系统可以通过在选定的字段中预编译后缀树来支持领先的通配符。

全文搜索的其他典型功能

  • 词法分析或标记化破坏a 非结构化文本块 个别单词,短语和 特殊令牌
  • 形态 分析,或者坍塌变化 一个给定单词的一个索引词; 例如,治疗“老鼠”和 “老鼠”,或“电气化”和 “电”作为同一个词
  • 排名测量 匹配记录的相似性 查询字符串

答案 1 :(得分:37)

FTS涉及索引文本字段中的单个单词,以便快速搜索许多记录。使用LIKE仍然需要您在字段中进行字符串搜索(线性或类似)。

答案 2 :(得分:17)

MySQL根据启用的全文搜索列的字词创建索引,并对此索引执行搜索。 MySQL使用复杂的算法来确定与搜索查询匹配的行。

此外,来自this SO answer

  

全文搜索有一些优势。

     

<强>索引:

     

类似的东西:

WHERE Foo LIKE '%Bar';
     

无法利用索引。它必须查看每一行,看它是否匹配。但是,全文索引可以。实际上,全文索引可以在匹配单词的顺序,这些单词的接近程度等方面提供更大的灵活性等。

     

<强>词干:

     

全文搜索可以阻止单词。如果搜索运行,则可以获得“运行”或“运行”的结果。大多数全文引擎都有各种语言的词典。

     

加权结果:

     

全文索引可以包含多个列。例如,您可以搜索“桃饼”,索引可以包含标题,关键字和正文。与标题匹配的结果可以加权更高,更相关,并且可以排序以显示在顶部附近。

     

<强>缺点:

     

全文索引可能很大,比标准B-TREE索引大很多倍。出于这个原因,许多提供数据库实例的托管提供商禁用此功能,或至少为此收取额外费用。例如,我上次检查过,Windows Azure不支持全文查询。

     

全文索引的更新速度也可能较慢。如果数据变化很大,则与标准索引相比可能会有一些滞后更新索引。

答案 3 :(得分:15)

仅使用通配符,并不是那么强大。

全文允许更复杂的搜索,包括And,Or,Not,甚至类似的声音效果(SOUNDEX)和更多项目。

我将开始查看SQL CONTAINS()FREETEXT()和相关的全文搜索项,以帮助更好地了解可用的内容。

答案 4 :(得分:10)

真正的区别在于扫描方法。对于全文搜索,单词(术语)用作散列键 - 每个键都与键(术语)出现的文档数组相关联。如下所示:

Document sets = {d1, d2, d3, d4, ... dn}
Term sets = {t1, t2, t3, .. tn}

现在,术语 - 文档矩阵(哪个文档的术语成员)可以表示为:

t1 -> {d1, d5, d9,.. dn}
t2 -> {d11, d50, d2,.. dn}
t3 -> {d23, d67, d34,.. dn}
:
tn -> {d90, d87, d57,.. dn}

当请求进入时,请求#34;获取包含单词/术语t1&#34的所有文档; - 然后返回文档集{d1, d5, d9,.. dn}。

你可以破解一个非规范化的表模式来存储文档 - MySQL表中的每一行都将被视为&#34; document&#34;并且TEXT列可以包含段落等。反向索引将包含作为散列键的术语和作为文档ID的行-id。

请记住,此SQL查询将具有或多或少的O(1)性能。查询将独立于

  1. TEXT列中的字数/术语数
  2. 符合条件的行/文档数
  3. 单词/术语的长度
  4. 例如,可以触发此SQL以提取与给定单词XYZ匹配的所有行:

    SELECT * 
    FROM   my_table 
    WHERE  MATCH (my_text_column) against ('XYZ' IN boolean mode) ;
    

    警告:如果向此查询添加ORDER BY,则运行时将根据几个参数而变化,其中一个参数是匹配的行/文档的数量。所以要小心。

    然而,LIKE却一无所获。它被迫线性扫描句子/字符串并找到所有匹配的术语。添加外卡增加了混乱。它可以很好地适用于小长度弦乐,你可以想象,但是对于较长的句子来说,它会失败。当有段落或整页文本等时,绝对没有可比性。

答案 5 :(得分:3)

FTS更高效,更强大(特别是对于断字符和词干功能)  ...但请检查您的要求,因为有时DB不支持所有语言,例如MSSQL不支持希腊文(请参阅本页http://msdn.microsoft.com/en-us/library/ms176076(v=sql.110).aspx