变量的优化规则

时间:2015-03-20 11:30:45

标签: arangodb

我观察到这两个语句之间的查询性能存在巨大差异:

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

后者比第一个花费的时间长五倍以上(两百万条记录的时间大于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)

1 个答案:

答案 0 :(得分:1)

第一个查询将执行少于第二个查询的一个计算。

在第一个查询中,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。

开始,此语法可用

自动检测上述内容并自动转换查询会很不错。可能将多个计算合并为一个的转换会有所帮助。