如何在Rails 3应用程序中实现更快的Search As You Type (SAYT) API

9

我在mysql数据库中有数百万条记录。我在Rails 3中为iPhone应用程序实现了一个普通的REST api,但SAYT功能响应非常缓慢。搜索数据库并返回结果需要很长时间。如何提高性能?

我已经对表进行了索引。我应该更深入地研究哪些方面,例如MySQL调优,或者我应该使用rails sphinx或sunspot吗?这会有所帮助,请给我您所有专家意见的帮助。


你能分享更多的信息吗?你正在搜索多少列?有哪些类型的字段?你能分享一下你现在使用的查询吗?你应该考虑使用全文搜索引擎,Elasticsearch是另一个不错的选择:http://railscasts.com/episodes?search=search - fatfrog
有多慢才算慢?你能发布一份Rails开发日志的要点,以便搜索请求吗?你的问题的答案很大程度上取决于是否在查询数据库、返回结果、两者都是、还是其他方面花费了最多的时间。在更改之前,请先进行性能分析! - carols10cents
6个回答

2
我同意一般性的回答:使用像Sphinx这样的搜索引擎(并限制返回的结果数量);它们被设计用于做你想要的事情。
然而,虽然数百万条记录听起来像很多,但你首先应该确定什么花费了很长时间。我非常喜欢Sphinx和ThinkingSphinx——它们将一个相当复杂的过程变得相当简单和容易。但最后,搜索引擎只是另一个需要管理、配置、学习和了解的系统。如果不必去那里,那就更容易了,对吧?
可能是查询,可能是返回数据所花费的时间(limit是你的好朋友!)。或者可能是你每秒收到数百个请求,也许因为自动完成的延迟太短了——如果每个字符都进行查找,快速打字者或多个用户很容易用没有对用户有用处的查询淹没服务器。
观察Rails日志,看看实际发生了什么。如果是简单的查询性能问题,执行复杂的全文搜索,那么,是的,那会很慢,而Sphinx则会值得一试。你的数据库有一个explain工具,通过一些工作,可以帮助你了解数据库如何获取结果。常见的是索引没有被使用。
缓存怎么样?Memcached是一个很棒的工具。或者甚至只需更改数据库的缓冲区大小设置,就可以允许它使用更多的内存进行缓存。

1

我也建议使用像Sphinx这样的全文搜索引擎。

有一个关于如何使用Sphinx和Rails的很好的视频教程,使用thinking_sphinx gem:

Railscast thinking_sphinx gem

使用该gem,您还可以通过添加字段权重来影响搜索结果的重要性:

Thinking Sphinx documentation

由于它是移动设备,我建议将发送到移动设备的结果数量保持在最小限度,正如madi已经提到的那样。

祝玩得开心!


1

如果你需要快速搜索数百万条记录,你可能需要使用 trie 类型的数据结构。http://en.wikipedia.org/wiki/Trie 中有 Ruby 的示例代码,如果需要帮助可以参考。

简单来说,trie 是一种高效的存储方法,用于跟踪哪些子元素属于哪些初始字符列表。

基本上,你的 SAYT 技术会接收一个字符串,并从 trie 的入口返回前 15 个结果左右。

当然,这取决于你的行有多相似,这将影响你的 RAM 使用情况。


1

我不确定您所说的更快搜索是什么意思,但将搜索结果限制在100个以增加可用性是很好的。因为没有多少用户会查看100条记录来进行搜索。

为了实现这样的搜索,我建议您包括关键字表。关键字表应该包括记录ID、与之相关联的关键字以及关键字在数据库中被交易的次数。

这样可以帮助您确定前100条记录和最准确的搜索结果。

还有许多算法,例如Map Reduce,可以并行运行。但我认为您的移动设备技术无法处理Map Reduce。


2
对于移动设备上的第一页搜索结果,我认为5-10个结果就足够了。 - carols10cents

0
根据您所查询的内容,以列开头匹配的LIKE查询可能会使用索引(在Postgres中我确定会使用,在MySQL中我不确定)。
因此,
Widget.where('name LIKE ?', "#{search_term}%").all

将使用数据库索引(至少在Postgres中),而

Widget.where('name LIKE ?', "%#{search_term}%").all

不会的。请注意搜索术语开头的%。使用ILIKE(不区分大小写)和LIKE(区分大小写)条件可能会产生不同的结果。阅读数据库文档。这可能是最简单的解决方法。

另一个回复提出的搜索引擎是另一个选择。如果您部署在Heroku上,有一些云搜索附加组件可以很容易地集成,但这可能仍然比微调查询工作量大一个数量级。


0
你可以制作一个最常搜索的表格,然后按照这种方式优先搜索,希望这能帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接