我有一个很大的索引定义,索引时间太长。我怀疑主要问题是由许多LEFT OUTER JOIN产生的。
我看到了this question,但无法找到有关使用source: :query
的文档,这似乎是解决方案的一部分。
我的索引定义和结果查询可以在这里找到:https://gist.github.com/jonsgold/fdd7660bf8bc98897612
如何优化生成的查询以便在索引编制期间更快地运行?
答案 0 :(得分:2)
对此的'标准'sphinx解决方案是使用远程查询。
http://sphinxsearch.com/docs/current.html#ex-ranged-queries
...将查询拆分成许多小部分,因此数据库服务器更有可能运行查询(而不是一个大查询)
但我不知道如何在Thinking Sphinx中实现这一点。在文档中看不到任何内容。可以帮助您编辑sphinx.conf,但也不确定TS将如何处理您手动编辑配置文件。
答案 1 :(得分:0)
这是最有效的解决方案(来自linked question)。基本上,您可以移除主要查询sql_query
的一部分,并将其单独定义为sql_joined_field
文件中的sphinx.conf
。
为每个sql_joined_field
添加所有相关的sql条件非常重要(例如,通过ID对模数进行分片索引)。这是新定义:
ThinkingSphinx::Index.define(
:incident,
with: :active_record,
delta?: false,
delta_processor: ThinkingSphinx::Deltas.processor_for(ThinkingSphinx::Deltas::ResqueDelta)
) do
indexes "SELECT incidents.id * 51 + 7 AS id, sites.name AS site FROM incidents LEFT OUTER JOIN sites ON sites.id = site_id WHERE incidents.deleted = 0 AND EXISTS (SELECT id FROM accounts WHERE accounts.status = 'enabled' AND incidents.account_id = id) ORDER BY id", as: :site, source: :query
...
has
...
end
ThinkingSphinx::Index.define(
:incident,
with: :active_record,
delta?: true,
delta_processor: ThinkingSphinx::Deltas.processor_for(ThinkingSphinx::Deltas::ResqueDelta)
) do
indexes "SELECT incidents.id * 51 + 7 AS id, sites.name AS site FROM incidents LEFT OUTER JOIN sites ON sites.id = site_id WHERE incidents.deleted = 0 AND incidents.delta = 1 AND EXISTS (SELECT id FROM accounts WHERE accounts.status = 'enabled' AND incidents.account_id = id) ORDER BY id", as: :site, source: :query
...
has
...
end
将字段site
定义为单独查询的魔力是该行末尾的选项source: :query
。
请注意,核心索引定义具有参数delta?: false
,而增量索引定义具有参数delta?: true
。这样我就可以在delta索引中使用条件WHERE incidents.delta = 1
并过滤掉不相关的记录。
我发现分片没有表现得更好,所以我恢复了一个统一的索引。
请在此处查看整个索引定义:https://gist.github.com/jonsgold/05e2aea640320ee9d8b2。
重要的是要记住!
必须手动处理Sphinx文档ID偏移量。也就是说,每当添加或删除另一个模型的索引时,我的计算文档ID都将更改。这必须更新。
因此,在我的示例中,如果我为其他模型(不是:incident
)添加了索引,则必须运行rake ts:configure
以找出我的新偏移并更改incidents.id * 51 + 7
相应