ArangoDB - IN运算符非常慢

时间:2015-12-10 11:07:11

标签: indexing database-performance arangodb

我在ArangoDB中使用IN运算符时会遇到一些性能问题。

简单地说,我有一个计算(在运行时)的数组,来自分裂函数,我想只获取Collection的选定元素,然后收集或过滤其他数据。

您可以在此处找到 AQL查询

LET toInclude = SPLIT('Collection/1,Collection/2,Collection/3', ',')

FOR result IN Collection
  FILTER result._id IN toInclude  
  COLLECT property = result.property 
  WITH COUNT INTO count
return  {property, count}

数组toInclude中的元素可以是300000+,查询可以花费超过10分钟来完成工作。

split - 函数在3秒内完成,property字段已编入索引,因此问题出在IN运算符中。

我可以做些什么来解决这些表演问题?

非常感谢!

丹尼尔

1 个答案:

答案 0 :(得分:4)

我在toInclude中对100,000个文档的集合中的500,000个字符串条目进行了查询。

完成2.7确实需要很长时间。执行时间约为4xx秒。查询花了很多时间来评估那里的FILTER IN运算符。实际上,将针对找到的每个文档评估FILTER条件。这将与我使用的数据进行大约100,000 x 500,000 / 2的比较。

在2.8中,相同的查询使用相同的数据需要大约2.7秒,因此问题似乎不会发生在那里。在2.8中有许多优化器更改,负责加速的那个更改是IN表达式将直接在索引中进行评估。 FILTER将在那里进行优化。

因此,一个修复就是使用ArangoDB 2.8(目前处于测试阶段)。

另一个修复方法是改进优化器,以检测查询中IN的右侧是否为const,以便它可以对结果进行排序,并可以使用二进制搜索进行IN(对数而不是线性复杂度)。但那还没有。

2.7的解决方法是单独计算IN列表,并将其作为数组插入到查询中。这样,IN列表将是一个常量值,优化器将能够对其进行预排序,以便它可以使用二进制搜索。但是,这需要在原始查询之外/之前执行SPLIT操作。

更新:在2.8中,现在有一个额外的优化程序规则可以为上述和其他案例预先排序IN列表值。这使IN运算符能够使用二进制搜索,具有对数复杂度,而不是某些情况下的线性复杂度。此更改将包含在2.8 beta2中。