[IR] Search Server - Sphinx
使用 Sphinx 更好地进行 MySQL 搜索 - IBM
尽管 MySQL 是一个出色的通用数据库,但是如果您的应用程序需要进行大量搜索,那么使用 Sphinx 可获得更好的性能。
尽管 Sphinx 是一种全文本搜索工具,但即使与非全文本查询一起使用,它仍然可以提高应用程序的速度。
本文将介绍如何针对此任务配置 Sphinx,其中包括一些示例查询,度量其执行时间,本文还将演示在考虑以某种通用的、系统的方式使用 Sphinx 时,更改中涉及的一些权衡方法。
简介
MySQL 是一个出色的综合性数据库,但是,对于需要进行大量搜索的应用程序,考虑采用具体的搜索实用工具可能会更好一些。
本文章将 Sphinx(一个著名的全文本搜索包)视为 MySQL 的替代品,用它来进行搜索,提高非全文本搜索的速度。
本文章研究此更改中涉及的权衡方法和说明,演示一些具体测试,并考虑以通用方式使用 Sphinx 所需的内容。
MySQL 或 Sphinx?
为什么会考虑使用 Sphinx 替换 MySQL?
比如说,以一个书店的搜索应用程序为例。用户可能会通过指定书名、作者、状态(新或旧)、版本(第一版或影印版)、封面(精装或平装)、出版商、出版年份、是否有作者签名和价格等内容查找书籍。
MySQL 通常不会使用多个索引(一个例外是索引合并优化;参阅 参考资料),因此优化所有可能搜索的唯一方法就是使用限制数量的多列索引,但这样做效果并不是很好。
但是,Sphinx 是一种搜索引擎,可以与 MySQL 很好地集成,也可以自己独立工作。它提供了高索引和搜索性能,支持通过 SphinxQL 进行查询。SphinxQL 是一种基于 Structured Query Language (SQL) 的语言。最后,Sphinx 能很好地向上扩展,能够使用分布式搜索功能处理包含几 TB 数据的数百万个文档。
Sphinx 可处理文档(可在数据库表或视图中保存)、文本字段(它索引的内容,提供全文本搜索)和属性(非文本值,可用于对结果进行筛选、排序和分组)。属性保存在随机存取内存 (RAM) 中以提高效率;请参阅 参考资料 中的 Sphinx 文档,了解实际大小计算公式。
在处理查询时,Sphinx 依赖于特殊索引文件。您必须为索引过程定义数据源,然后运行 indexer
程序。
另一种可能性是使用实时索引文件,您可以在牺牲一些效率的情况下立即更新该文件。我将在本文后面详细介绍这些方法。
提出问题:搜索引擎 与 数据库 的区别?
How do I know when I should use a search engine and when I should use a database?
- It depends on what type of information you are hoping to find and how you plan to use it.
- If you want credible, scholarly articles, you will have more success finding relevant sources in a library database free of charge.
- If you want Census data, it is more efficient to find that through a search engine that guides you to the appropriate government website.
数据库的一大特点是:数据类型。那么,决定了数据库的一个优势,数据间的关联性。
数据源下载:https://launchpad.net/test-db
~/bin/sphinx/etc> php test.php
FIRST TEST ... SINGLE TABLE
test 1 - MySQL 38 rows in 0.1912 secs
test 1 - Sphinx 38 rows in 0.0157 secs
SECOND TEST ... JOIN
test 2 - MySQL 5 rows in 0.1532 secs
test 2 - Sphinx 5 rows in 0.0020 secs
本示例仅考虑了静态搜索,它假定使用了常数表,但效果依然效果惊人。
实时更新的话:
对于本示例,我们假定旧数据在第一次写好之后没有进行任何修改。您可以通过实现 main+delta 方案来获得几乎实时的索引更新。这里采用的原理是:为旧数据和固定数据设置一个索引,为新数据设置另一个索引,这样就可以快速创建索引,因为数据比较小。然后,您需要做的就是查询两种索引文件并使用两种结果的组合。考虑使用索引合并来重新创建主索引,方法是合并一个之前的索引和一个增量索引(参阅 参考资料 中的 Sphinx 文档,了解有关的详细信息)。
结束语
您可以得出什么样结论?首先,使用 Sphinx 代替 MySQL 可以提供显著的性能优势。Sphinx 十分适用于搜索静态表。但是,对于经常更新的表,则无法使用 plain
索引文件。相反,您需要实施增量文件索引或更改为实时索引,这两种解决方案都会导致额外的性能成本。最后,高效使用 Sphinx 需要进行一些规划,因为您必须预定义所有必需的源和索引文件,当然,这不是一个缺点,只是普通常识。
使用 Sphinx 代替 MySQL 并不简单,但也没有复杂到需要排除这种方法。如果快速搜索速度是必需的,则值得考虑将所用的搜索引擎从 MySQL 更改为 Sphinx,即使您不是正在进行全文搜索。
既然这么高效,如何与SQL结合,1+1>2 呢?
sphinx实时索引效率很高,上千万条记录也能在不到一秒时间内搜索出来,这一点有时候可以作为数据库的预处理,
比如,搜索出新闻Id,再根据这些Id分页显示,效率很高,基本上如果是搜索导致并发性很高的网站,或搜索导致数据库性能成为瓶颈的网站,都可以这样处理一下,减少数据库的查询,我们都知道,数据库的like全查询,那是不走索引的,基本上几百万条数据可能效率就很低了。
故,类似于root对children掌握所有的关联信息,query是一个child信息,那么策略就是:
根据这个child信息找到root,例如ID, by Sphinx。再通过ID搜索出所有的孩子信息以及其他相关信息 by DB。
Coreseek + Sphinx + Mysql + PHP构建中文检索引擎
首先明确几个概念
Sphinx是开源的搜索引擎,它支持英文的全文检索。所以,如果单独搭建Sphinx,你就已经可以使用全文索引了。
但是往往我们要求的是中文索引,怎么做呢?国人提供了一个可供企业使用的,基于Sphinx的中文全文检索引擎。也就是说Coreseek实际上的内核还是Sphinx。那么他们的版本对应呢?
Coreseek发布了3.2.14版本和4.1版本,其中的3.2.14版本是2010年发布的,它是基于Sphinx0.9.9搜索引擎的。而4.1版本是2011年发布的,它是基于Sphinx2.0.2的。Sphinx从0.9.9到2.0.2还是有改变了很多的,有很多功能,比如sql_attr_string等是在0.9.9上面不能使用的。所以在安装之前请判断清楚你需要安装的是哪个版本,在google问题的时候也要弄清楚这个问题的问题和答案是针对哪个版本的。我个人强烈建议使用4.1版本。
网上有一篇文章说的是Sphinx和Coreseek是怎么安装的,其中它的coreseek安装这部分使用coreseek-4.1来替换就可以使用了。
Coreseek
选择基于Sphinx、结合MMSeg,开发出Coreseek中文全文检索引擎,并按照GPLv2协议发行,以供企业和个人解决中文搜索问题。
Sphinx
Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。Sphinx特别为一些脚本语言设计搜索API接口,如PHP,Python,Perl,Ruby等,同时为MySQL也设计了一个存储引擎插件。
Sphinx单一索引最大可包含1亿条记录,在1千万条记录情况下的查询速度为0.x秒(毫秒级)。
Sphinx创建索引的速度为:创建100万条记录的索引只需 3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而只包含最新10万条记录的增量索引,重建一次只需几十秒。
一个感想:
可能,Oracle数据库之所以牛,就是因为index做得好。
换句话说,这个数据库是传统数据库与精简版搜索引擎的结合体。
Sphinx 代码一些细节
Indexer程序就是根据配置好地分词算法,将获取到的记录进行分词,然后用倒排索引做数据结构保存起来。
Code download: http://sphinxsearch.com/downloads/release/
indexer.cpp 索引程序index的入口主函数
searchd.cpp 查询程序searchd的入口主函数
link
至于倒排索引的优化,请见:[IR] Compression