像Sphinx这样的全文搜索服务器如何工作?

时间:2012-04-24 09:34:57

标签: sql full-text-search search-engine sphinx thinking-sphinx

任何人都可以用简单的词语解释像Sphinx这样的全文服务器是如何工作的吗?在纯SQL中,可以使用这样的SQL查询来搜索文本中的某些关键字:

select * from items where name like '%keyword%';

但是在各种Sphinx插件生成的配置文件中,我根本看不到任何类似的查询。它们包含如下所示的SQL语句,它们似乎将搜索划分为不同的ID组:

SELECT (items.id * 5 + 1) AS id, ... 
       WHERE items.id >= $start AND items.id <= $end 
       GROUP BY items.id
..
SELECT * FROM items WHERE items.id = (($id - 1) / 5)

可以用简单的词语解释这些查询是如何工作的以及它们是如何生成的?

4 个答案:

答案 0 :(得分:17)

倒置索引是您问题的答案:http://en.wikipedia.org/wiki/Inverted_index

现在,当您通过sphinx运行sql查询时,它从数据库中获取数据并构造反向索引,该索引在Sphinx中就像一个哈希表,其中键是一个32位整数,使用crc32(word)和value是具有该单词的documentID列表。

这使它超级快。

现在你可以争辩说,即使是数据库也可以创建一个类似的结构,使搜索超高速。然而,最大的区别是Sphinx / Lucene / Solr索引就像单表数据库,不支持关系查询(JOIN)[来自​​MySQL性能博客]。请记住,索引通常只支持搜索,而不是数据的主要来源。因此,您的数据库可能处于“第三范式”,但索引将完全取消规范化,并且主要包含需要搜索的数据。

另一个可能的原因是数据库通常存在内部碎片,他们需要在巨大的请求上执行太多的半随机I / O任务。

这意味着,例如,考虑到数据库的索引体系结构,查询会导致索引进而导致数据。如果要恢复的数据被广泛传播,结果将花费很长时间,这似乎是数据库中发生的事情。

编辑:另外请查看cpp文件中的源代码,如searchd.cpp等真正的内部实现,我想你只是看到了PHP包装器。

答案 1 :(得分:4)

您正在查看的那些查询是sphinx使用的查询,用于从数据库中提取数据的副本,以放入其自己的索引。

Sphinx需要数据的副本来构建索引(其他答案已经提到了索引的工作原理)。然后,您从searchd守护程序中请求结果(匹配特定查询) - 它查询索引并返回匹配的文档。

您选择的特定示例看起来相当复杂,因为它只提取部分数据(可能是分片) - 出于性能原因将索引拆分为多个部分。并且正在使用范围查询 - 因此可以零碎地访问大数据集。

可以使用更简单的查询构建索引,例如

sql_query = select id,name,description from items

会创建一个sphinx索引,其中包含两个字段 - namedescription,可以搜索/查询。

搜索时,您将获得唯一的idhttp://sphinxsearch.com/info/faq/#row-storage

答案 2 :(得分:1)

全文搜索通常使用倒排索引的一个实现。简单来说,它会在标记(单词)中制作索引字段的内容,并保存对该行的引用,并由每个标记编制索引。例如,行#1为The yellow dog而行#2为The brown fox的字段将填充索引,如:

brown  -> row#2
dog    -> row#1
fox    -> row#2
The    -> row#1
The    -> row#2
yellow -> row#1

答案 3 :(得分:0)

问题的简短回答是MySQL等数据库专门用于存储和索引记录以及支持SQL子句(SELECT,PROJECT,JOIN等)。尽管它们可用于执行关键字搜索查询,但它们无法提供最佳性能和功能。像Sphinx这样的搜索引擎专为关键字搜索查询而设计,因此可以提供更好的支持。