什么是全文search与LIKE

我刚刚在SQL中读了一篇提到“全文search”的文章。

我只是想知道FTS和LIKE之间的区别是什么。 我读了几篇文章,但没有find解释得很好的东西。

一般来说,“精确”和“召回”之间是有折衷的。 高精度意味着更less的不相关结果(没有误报),而高回忆意味着更less的相关结果丢失(没有误报)。 使用LIKE操作符为您提供100%的精度,而且不会让步。 全文searchfunction为您提供了很大的灵活性,可以调整精确度以便更好地调用。

大多数全文search实现使用“倒排索引”。 这是一个索引,其中键是单个词,相关联的值是包含该词的logging集。 全文search被优化以计算这些logging集的交集,联合等,并且通常提供sortingalgorithm以量化给定logging与search关键字的匹配程度。

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

其他function的全文search典型

  • 词法分析或分词 – 将非结构化文本块分成单独的单词,短语和特殊的记号
  • 形态分析,或将给定单词的变异词汇拼合成一个索引词; 例如把“老鼠”和“老鼠”,或者“电气化”和“电”作为同一个词
  • sorting – 测量匹配logging与查询string的相似度

FTS涉及索引文本字段中的各个单词以便快速search多个logging。 使用LIKE仍然需要你在字段中进行stringsearch(线性或类似的)。

就像只使​​用通配符,并不是那么强大。

全文允许更复杂的search,包括和,或,不,甚至类似的声音结果(SOUNDEX)和更多的项目。

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

MySQL根据已启用的全文search列的字词创build一个索引,并在该索引上执行search。 MySQL使用复杂的algorithm来确定与search查询匹配的行。

全文search有一些优点。

索引:

就像是:

在哪里Foo喜欢'%酒吧'; 不能利用索引。 它必须看每一行,看看是否匹配。 全文索引,但是,可以。 事实上,全文索引可以在匹配词语的顺序,这些词汇的相近程度等方面提供更多的灵活性。

词干:

全文search可以阻止单词。 如果你search运行,你可以得到“跑”或“跑”的结果。 大多数全文引擎都有多种语言的词典。

加权结果:

全文索引可以包含多个列。 例如,您可以search“桃派”,索引可以包含标题,关键字和正文。 匹配标题的结果可以更高的权重,更相关的,可以sorting显示在顶部附近。

缺点:

全文索引可能很大,比标准的B-TREE索引大很多倍。 出于这个原因,许多提供数据库实例的托pipe提供者都会禁用此function,或者至less会为此收取额外费用。 例如,最后我查了一下,Windows Azure不支持全文查询。

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

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

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

现在的术语文档matrix(哪个文档的术语成员)可以表示为:

 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查询将具有或多或less的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却一无所获。 它被迫线性地扫描句子/string并find所有匹配的术语。 添加通配符会增加混乱。 如你所能想象的那样,它适用于小长度的string,但对于更长的句子将会失败。 当有一个段落或一整页的文字等绝对不可比

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