ThinkingSphinx group_by导致搜索速度慢

时间:2017-01-30 18:06:17

标签: mysql ruby-on-rails sphinx thinking-sphinx

设定:

  • Rails 4
  • MySQL的
  • ThinkingSphinx

我的应用中有一个模型(Record),有近5亿行。这个模型有32个字段,但我关注的特定Sphinx搜索只有nametokenname是我使用Sphinx搜索的内容,token是我想要返回在Rails中执行其他操作的内容。

我建立的指数是:

ThinkingSphinx::Index.define :records, :with => :real_time do
  # fields
  indexes name
  indexes token

  # attributes
  has token, as: :token_attr, type: :string
  # < several additional attributes >
end

我想要做的是在与:records匹配的name上查询Sphinx,并让它在数组中返回不同的 token字符串。

以下是我所拥有的:

Record.search("red", indices: %w(records), max_matches: num_tokens_i_need, group_by: :token_attr)

......其中num_tokens_i_need通常在数千(小于10,000)的某个地方

上述查询需要5-8分钟才能完成。但是,当我这么做时:

Record.search("red", indices: %w(records), max_matches: num_tokens_i_need).map(&:token).uniq

搜索速度极快(在几百毫秒内返回数百万条记录),但由于num_tokens_i_need电话,我无法返回.uniq

基本上我需要做的是快速进行Sphinx搜索,这会给我一个给定术语的确切数量的不同令牌(例如&#34; red&#34;)。

如果看到我的sphinx.conf或其他任何内容会有帮助,请告诉我。

1 个答案:

答案 0 :(得分:0)

Sphinx docs注意到分组是在内存中完成的,因此,为了获得分组搜索结果,每个单个文档的属性需要在某个时刻在内存中。鉴于您的记录索引中有数百万个文档,我猜这是导致速度缓慢的原因。

请记住,在第二个示例中,数百万条记录可能与您的查询匹配,但它们并非全部由Sphinx返回(并且匹配仅在字段上完成,属性不涉及),这是为什么该查询更快。

关于更好的前进方向的一些想法:

  • 如果您只想要名称与完全匹配的Record实例中的令牌,那么SQL可能是这项工作的更好工具。即使是部分匹配,使用数据库的模糊匹配也可能更快。
  • 如果您只是在令牌的数字之后,而不是令牌值,那么Sphinx确实不适合这项工作。它并非基于聚合构建,因此它没有针对您正在运行的查询进行调整。
  • 如果关键字值(在您的示例中为red)是已知集(而非用户提供的),您可以缓存这些值并定期重新计算(每天一次?)。

这些都不是明显的赢家,但希望它们可以帮助您找到更好的解决方案。