ArangoDB通过_id获取文档,每个查询都有缓存

时间:2015-10-14 21:24:54

标签: database performance arangodb aql

拥有文档集“items”和“dictionary1”,“dictionary2”

collection "items" have 50000 records, like
{
label:"..."
dict1: "dictionary1/33333"
dict2: "dictionary2/44444"
....
}

当我加入字典

FOR item IN items
LET dictname = FIRST(FOR d IN dictionary1 FILTER d._id == item.dict1 RETURN d.name)
RETURN { _id: item._id, name: item.name, dict: dictname }

对于这个简单的任务,查询执行时间〜150ms。 对于实验,我是一个_id

的强制字典
FOR item IN items
LET dictname = FIRST(FOR d IN dictionary1 FILTER d._id == "dictionary1/10000" RETURN d.name)
RETURN { _id: item._id, name: item.name, dict: dictname }

查询执行时间~130ms

我也是一个尝试过的DOCUMENT函数

FOR item IN items
LET dictname = DOCUMENT("dictionary1", "dictionary1/10000")
RETURN { _id: item._id, name: item.name, dict: dictname.name }

查询执行时间~1500ms :((

简单阅读收藏:

FOR item IN items
RETURN { _id: item._id, name: item.name }

查询执行时间~30ms

因此,当我通过_id 50000次获取相同文档时,结果不会被缓存。 在一个集合中具有重复内容的变体对我没用。 现在我将逻辑移到客户端,在内存中选择所有字典并在查询后加入,并且有~60ms,但我不喜欢这种方法,它错了。

在短时间内以任何方式获得加入词典(80%相同的_id)的结果?

1 个答案:

答案 0 :(得分:1)

如果您确定在dictionary1中为您在外部循环中循环的每个items中存在匹配项,则可以将查询简化为更简单的等连接这样:

FOR item IN items
  FOR d IN dictionary1 
    FILTER d._id == item.dict1
    RETURN { _id: item._id, name: item.name, dict: d.name }

这消除了对相关子查询和函数调用的需要。但是,如果每个dictionary都有匹配的item条目,则其结果将仅等同于原始子查询解决方案。如果dictionary没有item条目,则equi-join查询将禁止它。

如果不清楚dictionary1中是否有条目,并且您希望为不匹配返回null,则可以将子查询解决方案简化为(这将删除对FIRST的函数调用):

FOR item IN items
  LET sub = (FOR d IN dictionary1 
    FILTER d._id == item.dict1
    RETURN d.name
  )
  RETURN { _id: item._id, name: item.name, dict: sub[0] }

除此之外,加入_key属性而非加入_id可能会提供较小的加速,因为_key的生成时间比_id更短且更复杂。但这需要将连接值存储在items中,而不需要字典集合名称前缀。

上述建议不应提供数量级的运行时改进,但可能会有所帮助。