什么是全文搜索与喜欢


133

我刚刚读了一篇有关SQL中“全文本搜索”的文章。

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

Answers:


164

通常,在“精度”和“召回”之间需要权衡。高精度意味着呈现的无关结果更少(无误报),而高召回率则意味着较少的相关结果缺失(无误报)。使用LIKE运算符可为您提供100%的精度,而无需进行召回优惠。全文搜索功能为您提供了很大的灵活性,可以降低精度,以实现更好的召回率。

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

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

全文搜索的其他典型功能包括

  • 词法分析或标记化-将非结构化文本块分成单个单词,短语和特殊标记
  • 形态分析或词干分析-将给定单词的变体折叠为一个索引词;例如,将“老鼠”和“鼠标”或“电气化”和“电”视为同一个词
  • 排名-测量匹配记录与查询字符串的相似性

2
@VipinJain的答案中
ychaouche


23

MySQL从已启用的全文搜索列的单词创建索引,然后对该索引执行搜索。MySQL使用复杂的算法来确定与搜索查询匹配的行。

另外,从这个SO答案

全文搜索有一些优势。

索引:

就像是:

WHERE Foo LIKE '%Bar';

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

抽干:

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

加权结果:

全文索引可以包含多个列。例如,您可以搜索“桃派”,并且索引可以包括标题,关键字和正文。与标题匹配的结果的权重越高,相关性越高,并且可以对其进行排序以显示在顶部附近。

缺点:

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

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


16

Like仅使用通配符,功能不那么强大。

全文允许更复杂的搜索,包括“与”,“或”,“不”,甚至相似的发音结果(SOUNDEX)和更多项目。

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


2
我强烈建议大家检查SOUNDEX
sotn

11

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

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}

当请求进入要求“获取包含单词/词条t1的所有文档”时,将{d1, d5, d9,.. dn返回文档集}。

您可以修改非规范化的表架构来存储文档-MySQL表中的每一行都将被视为“文档”,而TEXT列可能包含一个段落等。反向索引将包含诸如哈希键和行ID的术语作为文档ID。

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

  1. TEXT列中的单词/术语数
  2. 符合条件的行数/文档数
  3. 单词/术语的长度

例如,可以触发此SQL以提取与给定单词XYZ匹配的所有行:

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

注意:如果将ORDER BY添加到此查询,则运行时将根据多个参数而有所不同,其中一个是匹配的行/文档数。所以要当心。

但是,LIKE对此一无所获。它被迫线性扫描句子/字符串并找到所有匹配的术语。添加通配符会增加混乱。可以想象,它对于较小长度的字符串非常有用,但是对于较长的句子却会失败。当有段落或整页文本等时,绝对不可比。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.