我观察到这两个语句之间的查询性能存在巨大差异:
FOR w IN relatedAffils
COLLECT from = w._from, to = w._to INTO agg
INSERT { "_from": from, "_to": to, "weight": LENGTH(agg),
"fromAff": DOCUMENT(from).affiliation
} INTO relatedAffilsAggregated
和
FOR w IN relatedAffils
COLLECT from = w._from, to = w._to INTO agg
LET fromDoc = DOCUMENT(from)
INSERT { "_from": from, "_to": to, "weight": LENGTH(agg),
"fromAff": fromDoc.affiliation
} INTO relatedAffilsAggregated
后者花费的时间是第一个的五倍多(200 万条记录> 30 分钟(。也许这是因为在第二个版本中我使用了临时变量。也许这是另一个优化规则可能有意义的一点?
再比如:
FOR w IN relatedAffilsAggregated
FILTER DOCUMENT(w._from).country == "deu"
FILTER DOCUMENT(w._to).affiliation < DOCUMENT(w._from).affiliation
SORT w.weight DESC
LIMIT 1000
RETURN CONCAT( w.weight, ": (", DOCUMENT(w._from).country, ",", `DOCUMENT(w._to).country, ") ", DOCUMENT(w._from).affiliation, " <----> ", DOCUMENT(w._to).affiliation)`
需要大约 30 秒,而我在 30 分钟后使用变量杀死了替代方案。
FOR w IN relatedAffilsAggregated
LET fromDoc = DOCUMENT(w._from)
FILTER fromDoc.country == "deu"
LET toDoc = DOCUMENT(w._to)
FILTER fromDoc.affiliation < toDoc.affiliation
SORT w.weight DESC
LIMIT 1000
RETURN CONCAT( w.weight, ": (", fromDoc.country, ",", toDoc.country, ") ", fromDoc.affiliation, " <----> ", toDoc.affiliation)
第一个查询将比第二个查询少执行一个计算。
在第一个查询中,DOCUMENT(from).affiliation
将与要插入的对象一起计算。
在第二个查询中,fromDoc
有一个额外的计算,这个变量的内容将在查询中随身携带,进入INSERT
。
通过重写LET
声明,可以使第二个查询更有效一些,如下所示:
LET fromDoc = DOCUMENT(from).affiliation
并且仅使用fromDoc
而不是fromDoc.affiliation
INSERT
.这会将 fromDoc
变量中的数据量从整个文档减少到只有一个属性。
另一件事是,在两个查询中使用INTO agg
都非常昂贵。agg
所需要的只是它的长度,因此INTO
子句可以更改为:
INTO agg = 1
这将再次将agg
中的数据量减少到一个简单的数字,而不是完整的文档。此语法从 2.4 开始可用。
自动检测上述内容并自动转换查询会很好。将多个计算合并为一个计算的转换可能会有所帮助。