首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AQL优化-按月遍历

AQL优化-按月遍历
EN

Stack Overflow用户
提问于 2016-08-25 21:31:49
回答 1查看 83关注 0票数 1

在ArangoDB中,我有一个包含配置文件消息的图表。为了报告目的,我需要汇总过去12个月每个月特定类别消息的消息数量。

每个邮件的日期和类别位于配置文件和消息之间的每一个边缘。

目前,我有:

代码语言:javascript
复制
for mo in 0..11
    let month = DATE_MONTH(DATE_SUBTRACT(DATE_NOW(),mo,"month"))
    let msgCount = count(
        for v, e in outbound "profileId" graph 'MyGraph'
            filter e.category == "myCategory" && DATE_MONTH(e.date) == month
            return 1
        )
    return {month: month, msgCount: msgCount}

这个查询在超过1秒内执行,对于这个over应用程序来说,这有点慢,因为我需要为几个类别创建和可视化这个报告。

是否有任何优化能够更快地产生相同的结果?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-31 09:53:42

分析查询

使用db._explain()显示了以下内容:

代码语言:javascript
复制
Execution plan:
 Id   NodeType            Est.   Comment
  1   SingletonNode          1   * ROOT
  2   CalculationNode        1     - LET #7 = 0 .. 11   /* range */   /* simple expression */
  3   EnumerateListNode     12     - FOR mo IN #7   /* list iteration */
  4   CalculationNode       12       - LET month = DATE_MONTH(DATE_SUBTRACT(DATE_NOW(), mo, "month"))   /* v8 expression */
 11   SubqueryNode          12       - LET #4 = ...   /* subquery */
  5   SingletonNode          1         * ROOT
  9   CalculationNode        1           - LET #11 = 1   /* json expression */   /* const assignment */
  6   TraversalNode          1           - FOR v  /* vertex */, e  /* edge */ IN 1..1  /* min..maxPathDepth */ OUTBOUND 'profileId' /* startnode */  GRAPH 'MyGraph'
  7   CalculationNode        1           - LET #9 = ((e.`category` == "myCategory") && (DATE_MONTH(e.`date`) == month))   /* v8 expression */
  8   FilterNode             1           - FILTER #9
 10   ReturnNode             1           - RETURN #11
 13   CalculationNode       12       - LET #13 = { "month" : month, "msgCount" : COUNT(#4) }   /* simple expression */
 14   ReturnNode            12       - RETURN #13

Indexes used:
 none

Traversals on graphs:
 Id   Depth   Vertex collections   Edge collections   Filter conditions
  6   1..1    persons              knows              

Optimization rules applied:
 Id   RuleName
  1   move-calculations-up
  2   remove-unnecessary-calculations

它可以告诉我们以下几点:

  • 在遍历中,我们使用V8表达式,这是昂贵的。
  • 由于您正在执行一个复杂的筛选器表达式,所以不能在遍历器内部执行--因此在遍历完成后应用筛选。

你能做些什么来改善这种情况

您应该找到一种将复杂计算移出迭代的方法。虽然使用DATE_*函数可能很方便,但速度不快。应该计算要预先筛选的字符串年份:月份,然后在查询中对计算的字符串进行范围比较:

代码语言:javascript
复制
FILTER e.date > '2016:04:' && e.date < '2016:05:'

Nate的执行情况:

代码语言:javascript
复制
for mo in 0..11
    let month = date_subtract(concat(left(date_iso8601(date_now()),7),'-01T00:00:00.000Z'), mo, "month")
    let nextMonth = date_subtract(concat(left(date_iso8601(date_now()),7),'-01T00:00:00.000Z'), mo-1, "month")
    let monthNumber = date_month(month)
    let msgCount = count(
        for v, e in outbound "profileId" graph "MyGraph"
            filter e.category == 'myCategory' && e.date > month && e.date < nextMonth
            return 1
            )
    return {month: monthNumber, msgCount: msgCount}

这大大加快了查询速度(快5倍)!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39155025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档