1

拥有文档集合“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 }

查询执行时间 ~ 150 毫秒对于这个简单的任务来说太多了。对于实验,我是一个 _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)的结果?

4

1 回答 1

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. 如果 a 没有dictionary条目item,则 equi-join 查询将简单地抑制它。

如果不清楚是否会有条目dictionary1,并且您希望nulls 因不匹配而返回,则子查询解决方案可以简化为(这将删除对 的函数调用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没有字典集合名称前缀的情况下存储连接值。

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

于 2015-10-20T13:07:14.103 回答